Set-up

rm(list = ls())
library(dplyr)
library(wesanderson)
library(GillespieSSA)
library(tidyverse)

Background

The traditionally held belief that most modern infectious diseases emerged when humans began living in larger agricultural settlements has been challenged by studies of modern hunter-gatherers. This study will investigate which emerging pathogens may persist in hunter-gatherer groups by constructing a compartment model of infectious disease transmission that accounts for demography and multi-band structure. This study will look to understand how the critical community size required to sustain an outbreak is affected by host population dynamics. We show that metapopulation structure increases the probability of a respiratory pathogen with waning immunity persisting after 3 years. The probability of persistence increases with the number of sub-populations but is largely determined by the duration of immunity. Understanding the origins of infectious diseases is an important area of research that will lead to improved strategies for reducing their global burden.

This report will cover the full analysis undertaken to generate the results used in my MSc project. A full description of the research project aims and methods can be found in the final paper in the Hunter_Gatherer_models GitHub repository. Some code used in this project was adapted from the tutorials attached to the GillespieSSA package.

Model Parameter estimation

Agta Hunter-Gatherer Demography

Modern-day hunter-gatherers are often used to make inferences about pre-agricultural human populations. This study modeled the host population on a group of indigenous hunter-gatherers from the Northern Phillipines known as the Agta. Information regarding births, deaths and population size were obtain from a study conducted by Headland et al., (2011). Authors conducted a census-like survey of the Agta that followed $$4,300 individuals over the period of 1950-2010. This date was first explored to understand Agta demography.

agta_demo <- read.csv("Agta_Data/AgtaPopDynamics_Headland2007.csv")

ggplot(agta_demo, aes(x=Year)) +
  geom_line(aes(y=PopSize), colour = wes_palettes$Darjeeling1[1]) +
  geom_line(aes(y=Births), colour = wes_palettes$Darjeeling1[2]) +
  geom_line(aes(y=Deaths), colour = wes_palettes$Darjeeling1[3]) +
  theme_bw()

Population Size

hist(agta_demo$PopSize)

summary(agta_demo$PopSize)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  133.0   177.0   213.0   211.4   228.0   295.0 

Births

hist(agta_demo$Births)

summary(agta_demo$Births)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
   4.00    8.00   10.00   10.33   12.25   15.00       1 

Deaths

hist(agta_demo$Deaths)

summary(agta_demo$Deaths)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
  2.000   5.000   7.000   7.683  10.000  23.000       1 

Birth/Death rate per person per day

Birth rate was estimated from this data by taking the mean of the annual number of births divided by two times the annual number of females. This was then scaled appropriately to obtain the daily mean birth rate per person.

agta_demo <- agta_demo %>%
  mutate(Birth_rate = Births/(Female*2),
         Birth_rate_daily = (1 + Birth_rate) ^ (1/365) - 1,
         Death_rate = (Deaths/PopSize),
         Death_rate_daily = (1 + Death_rate) ^ (1/365) - 1,
         PopChange = (diff = PopSize - lag(PopSize, default = first(PopSize))),
         PopChange_rate = abs(PopChange)/PopSize,
         PopChange_rate_daily = (1 + PopChange_rate) ^ (1/365) - 1)
head(agta_demo)


hist(agta_demo$Birth_rate)

hist(agta_demo$Death_rate)


ggplot(agta_demo, aes(x=Year)) +
  geom_line(aes(y=Birth_rate), colour = wes_palettes$Darjeeling1[2]) +
  geom_line(aes(y=Death_rate), colour = wes_palettes$Darjeeling1[3]) +
  theme_bw()


demo_sum <- agta_demo %>%
  select(PopSize, Birth_rate, Birth_rate_daily, Death_rate, Death_rate_daily, PopChange_rate, PopChange_rate_daily) %>%
    summarise(across(
    .cols = is.numeric, 
    .fns = list(Mean = mean, SD = sd), na.rm = TRUE, 
    .names = "{col}_{fn}"
    ))
demo_sum 

demo_sum <- as.list(demo_sum)

Agta Band Size

Data regarding camp size of Agta hunter-gatherers was obtained from a study of 615 individuals from 15 camps in in the municipality of Palanan, the Northern Philippines published by Dyble et al. (2021).

# Import Camp data from Mark Dyble
camps.data <- read_csv("Agta_Data/camps.csv")
New names:Rows: 15 Columns: 9── Column specification ──────────────────────────────────────────────────────
Delimiter: ","
chr (1): camp_name
dbl (8): ...1, camp_total, camp_adult_men, camp_adult_women, camp_all_r, c...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(camps.data)
# Explore camp size
hist(camps.data$camp_total)


camp.size <- camps.data %>%
  summarise(mean = mean(camp_total),
            sd = sd(camp_total),
            min = min(camp_total),
            max = max(camp_total),
            var = var(camp_total))
camp.size

Pathogen X

For the purpose of this investigation we formulated a hypothetical respiratory pathogen, referred to as pathogen X. Taking into account the biological trade-offs between high transmissibility and high pathogenicity, pathogen X was decided to be highly infectious with a relatively low case fatality rate of 0.005. Transmission occurred via close contact with an infected individual. Infection was characterised by a latent period of 5.7 days followed by an infectious period of 5 days. Individuals who recovered from infection were immune for 100 days, after which immunity waned and individuals became susceptible to re-infection. Based on these characteristics, the parameters in table 1 were assumed and input into the final models.

Parameter Rate Value
\(\beta\) Transmission 0.6
\(\sigma\) Infectious 0.175
\(\gamma\) Recovery 0.2
\(\alpha\) Death from Infection 0.001
\(\omega\) Waning Immunity 0.01

Single Population Model

To investigate the persistence of a hypothetical respiratory pathogen in hunter-gatherers, this study chose to simulate disease transmission using a compartment model approach as outlined in the introduction. Two models were constructed to investigate compare the effect of metapopulation structure on disease persistence. This first describes the transmission of a pathogen within a single population with demography and waning immunity to re-infection over time.


Figure 1 - Flow diagram of SEIRS model of transmission
Figure 1 - Flow diagram of SEIRS model of transmission




\[\begin{align*} \frac{{{\mathrm{d}}S}}{{{\mathrm{d}}t}} & = \underbrace {\mu N}_{{\mathrm{birth}}}~ - ~\underbrace {\frac{\beta SI}{N}}_{{\mathrm{infection}}}~~ + \underbrace {\omega R}_{{\mathrm{lost}}\,{\mathrm{immunity}}} - \underbrace {\mu S}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}E}}{{{\mathrm{d}}t}} & = \underbrace {\frac{\beta SI}{N}}_{{\mathrm{infection}}}~ - ~\underbrace {\sigma E}_{{\mathrm{latency}}} - \underbrace {\mu E}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}I}}{{{\mathrm{d}}t}} & = \underbrace {\sigma E}_{{\mathrm{latency}}} - \underbrace {\gamma I}_{{\mathrm{recovery}}} - ~\underbrace {\left( {\mu + \alpha } \right)I}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}R}}{{{\mathrm{d}}t}} & = \underbrace {\gamma I}_{{\mathrm{recovery}}} - \underbrace {\omega R}_{{\mathrm{lost}}\ {\mathrm{immunity}}} - \underbrace {\mu R}_{{\mathrm{death}}} \end{align*}\]



Where transmission is frequency dependent, \({\frac{\beta SI}{N}}\), \(\frac{1}{\sigma}\) is the duration of the latent phase, \(\frac{1}{\gamma}\) is the duration of infection, \(\frac{1}{\omega}\) is the duration of immunity and death from infection occurs at the rate \(\alpha\). Individuals can be born into S and die naturally from any compartment at a rate of \(\mu\).

Model Set-up

Model was set up with a single randomly selected camp size with a single infected individual and parameters for pathogen X.

# Define Paramenters
N <-    sample(camps.data$camp_total, 1)    # Population size
initial_infected <-  1    # Initial infected
simName <- "SEIRS model"       # Simulation name
tf <- 365*3

#Collect parameters
parms <- list(
  beta = 0.6,
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

#Create the named initial state vector for the U-patch system.

x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

names(x0) <- c("S","E","I", "R", "N")


# Define the state change matrix for a single patch
nu <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
a <-c(
        paste0("(beta*I/N)*S"), # Infection
        paste0("sigma*E"),                                       # Becomes infecious
        paste0("gamma*I"),                                       # Recovery from infection
        paste0("omega*R"),       # Loss of immunity
        paste0("mu*N"),                             # Births
        paste0("mu*S"),                                             # Deaths (S)
        paste0("mu*E"),                                             # Deaths (E)
        paste0("mu*I"),                                             # Deaths (I)
        paste0("mu*R"),                                             # Deaths (R)
        paste0("alpha*I")                                           # Deaths from infection
        
      )

Define functions to calculate R0 and expected number of susceptibles at equilibrium, and critical community size (Diekmann et al., 2012).

 R0 <- function(parms) {
   (parms$sigma/(parms$sigma + parms$mu)) * (parms$beta/parms$gamma + parms$mu + parms$alpha)
 } 
  
EIE <- function(R0, parms) {
  y = ((R0 - 1) * parms$omega) / (parms$gamma * R0)
  return(y)
}

CCS <- function(epsilon, R0) {
  y = 1/((epsilon^2)*((1-(1/R0))^2))
  return(y)
}

Run Single Population Model


# Calculate R0, expected number of infecteds at equilibrium, magnitude of oscillation and CCS
R0_single <- R0(parms)
R0_single

EIE_single <- EIE(R0_single, parms) # proportion of expected infecteds at equilibrium
EIE_single

expexted_infecteds <- EIE_single*N # number of expected infecteds at equilibrium
expexted_infecteds

sqrt(N) # magnitude of oscillations 

epsilon <- (5.7/365)/23 # duration of infection in years divided by avg life expectancy 
CCS_single <- CCS(epsilon, R0_single) # Average life expectancy as per Kaplan (crude)
CCS_single
# Run simulations with the Direct method
set.seed(21)
out <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
) 



## Extra Plots
plot_data <- out$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

single_plot <- ggplot(data = plot_data, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  labs(x="Time (Days)",
       y="Number of Individuals", 
       colour="State")+
  geom_hline(yintercept = expexted_infecteds, linetype = 'dashed') +
  theme_bw()

single_plot

ggsave(filename = "single_plot.pdf", 
       plot = single_plot,
       device = "pdf",
       width = 7, 
       height = 3,
       path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
plot_data %>%
  filter(state == "I") %>%
  slice_max(count)

Outbreak peaked at day 25 with 14 infected individuals.

## Run multiple simulations and saving output
num_sims <- 1000
sim_list <- list()
sim_list <- vector("list", length = num_sims)

for (i in 1:num_sims){
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  set.seed(i)
  out_100 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data <- out_100$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list[[i]] <- sim_data
}

sim_output <- bind_rows(sim_list)
# Summary table of endpoint data
sim_output <- sim_output %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
head(sim_output)

# Make Summary Table of output
sim_summary <- sim_output %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100, 
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary

Varying waining immunity

Waning immunity was thought to play an important role in the persistence of pathogen X so we incrementally increased the duration of immunity (by decreasing \(\omega\)) and calculated the probability of persistence after 3 years in 1000 stochastic simulations. Duration of immunity was increased from 1 day to a year.

0 Days

#Collect parameters
parms_0 <- parms
parms_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_0 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_0 <- out_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_0 <- ggplot(data = plot_data_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_0
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_0 <- list()
sim_list_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_0 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_0 <- out_100_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_0[[i]] <- sim_data_0
}

sim_output_0 <- bind_rows(sim_list_0)
# Summary table of endpoint data
sim_output_0 <- sim_output_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_0

# Make Summary Table of output
sim_summary_0 <- sim_output_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_0

1 Days

#Collect parameters
parms_1 <- parms
parms_1$omega <- 1


# Run simulations with the Direct method
set.seed(4)
out_1 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_1,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_1 <- out_1$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_1 <- ggplot(data = plot_data_1, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_1
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_1 <- list()
sim_list_1 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_1 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_1 <- out_100_1$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_1[[i]] <- sim_data_1
}

sim_output_1 <- bind_rows(sim_list_1)
# Summary table of endpoint data
sim_output_1 <- sim_output_1 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_1

# Make Summary Table of output
sim_summary_1 <- sim_output_1 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_1

3 Days

#Collect parameters
parms_3 <- parms
parms_3$omega <- 1/3


# Run simulations with the Direct method
set.seed(4)
out_3 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_3,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3 <- out_3$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3 <- ggplot(data = plot_data_3, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3 <- list()
sim_list_3 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_3 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3 <- out_100_3$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_3[[i]] <- sim_data_3
}

sim_output_3 <- bind_rows(sim_list_3)
# Summary table of endpoint data
sim_output_3 <- sim_output_3 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3

# Make Summary Table of output
sim_summary_3 <- sim_output_3 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3

7 Days

#Collect parameters
parms_7 <- parms
parms_7$omega <- 1/7


# Run simulations with the Direct method
set.seed(4)
out_7 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_7,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_7 <- out_7$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_7 <- ggplot(data = plot_data_7, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_7
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_7 <- list()
sim_list_7 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_7 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_7 <- out_100_7$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_7[[i]] <- sim_data_7
}

sim_output_7 <- bind_rows(sim_list_7)
# Summary table of endpoint data
sim_output_7 <- sim_output_7 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_7

# Make Summary Table of output
sim_summary_7 <- sim_output_7 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_7

10 Days

#Collect parameters
parms_10 <- parms
parms_10$omega <- 1/10


# Run simulations with the Direct method
set.seed(4)
out_10 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_10 <- out_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_10 <- ggplot(data = plot_data_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_10
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_10 <- list()
sim_list_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_10 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_10 <- out_100_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_10[[i]] <- sim_data_10
}

sim_output_10 <- bind_rows(sim_list_10)
# Summary table of endpoint data
sim_output_10 <- sim_output_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_10

# Make Summary Table of output
sim_summary_10 <- sim_output_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_10

20 Days

#Collect parameters
parms_20 <- parms
parms_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_20 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_20 <- out_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_20 <- ggplot(data = plot_data_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_20
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_20 <- list()
sim_list_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_20 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_20 <- out_100_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_20[[i]] <- sim_data_20
}

sim_output_20 <- bind_rows(sim_list_20)
# Summary table of endpoint data
sim_output_20 <- sim_output_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_20

# Make Summary Table of output
sim_summary_20 <- sim_output_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_20

30 Days

#Collect parameters
parms_30 <- parms
parms_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_30 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_30 <- out_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_30 <- ggplot(data = plot_data_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_30
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_30 <- list()
sim_list_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_30 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_30 <- out_100_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_30[[i]] <- sim_data_30
}

sim_output_30 <- bind_rows(sim_list_30)
# Summary table of endpoint data
sim_output_30 <- sim_output_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_30

# Make Summary Table of output
sim_summary_30 <- sim_output_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_30

40 Days

#Collect parameters
parms_40 <- parms
parms_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_40 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_40 <- out_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_40 <- ggplot(data = plot_data_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_40
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_40 <- list()
sim_list_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_40 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_40 <- out_100_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_40[[i]] <- sim_data_40
}

sim_output_40 <- bind_rows(sim_list_40)
# Summary table of endpoint data
sim_output_40 <- sim_output_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_40

# Make Summary Table of output
sim_summary_40 <- sim_output_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_40

50 Days

#Collect parameters
parms_50 <- parms
parms_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_50 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_50 <- out_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_50 <- ggplot(data = plot_data_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_50
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_50 <- list()
sim_list_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_50 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_50 <- out_100_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_50[[i]] <- sim_data_50
}

sim_output_50 <- bind_rows(sim_list_50)
# Summary table of endpoint data
sim_output_50 <- sim_output_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_50

# Make Summary Table of output
sim_summary_50 <- sim_output_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_50

60 Days

#Collect parameters
parms_60 <- parms
parms_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_60 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_60 <- out_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_60 <- ggplot(data = plot_data_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_60
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_60 <- list()
sim_list_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_60 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_60 <- out_100_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_60[[i]] <- sim_data_60
}

sim_output_60 <- bind_rows(sim_list_60)
# Summary table of endpoint data
sim_output_60 <- sim_output_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_60

# Make Summary Table of output
sim_summary_60 <- sim_output_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_60

70 Days

#Collect parameters
parms_70 <- parms
parms_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_70 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_70 <- out_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_70 <- ggplot(data = plot_data_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_70
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_70 <- list()
sim_list_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_70 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_70 <- out_100_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_70[[i]] <- sim_data_70
}

sim_output_70 <- bind_rows(sim_list_70)
# Summary table of endpoint data
sim_output_70 <- sim_output_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_70

# Make Summary Table of output
sim_summary_70 <- sim_output_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_70

80 Days

#Collect parameters
parms_80 <- parms
parms_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_80 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_80 <- out_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_80 <- ggplot(data = plot_data_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_80
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_80 <- list()
sim_list_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_80 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_80 <- out_100_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_80[[i]] <- sim_data_80
}

sim_output_80 <- bind_rows(sim_list_80)
# Summary table of endpoint data
sim_output_80 <- sim_output_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_80

# Make Summary Table of output
sim_summary_80 <- sim_output_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_80

150 Days

#Collect parameters
parms_150 <- parms
parms_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_150 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_150 <- out_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_150 <- ggplot(data = plot_data_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_150
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_150 <- list()
sim_list_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_150 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_150 <- out_100_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_150[[i]] <- sim_data_150
}

sim_output_150 <- bind_rows(sim_list_150)
# Summary table of endpoint data
sim_output_150 <- sim_output_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_150

# Make Summary Table of output
sim_summary_150 <- sim_output_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_150

180 Days

#Collect parameters
parms_180 <- parms
parms_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(4)
out_100 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_180 <- out_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_180 <- ggplot(data = plot_data_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_180
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_180 <- list()
sim_list_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_180 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_180 <- out_100_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_180[[i]] <- sim_data_180
}

sim_output_180 <- bind_rows(sim_list_180)
# Summary table of endpoint data
sim_output_180 <- sim_output_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_180

# Make Summary Table of output
sim_summary_180 <- sim_output_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_180

365 Days

#Collect parameters
parms_365 <- parms
parms_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_365 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_365 <- out_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_365 <- ggplot(data = plot_data_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_365
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_365 <- list()
sim_list_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_365 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_365 <- out_100_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_365[[i]] <- sim_data_365
}

sim_output_365 <- bind_rows(sim_list_365)
# Summary table of endpoint data
sim_output_365 <- sim_output_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_365

# Make Summary Table of output
sim_summary_365 <- sim_output_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_365

Results

waning_results_single <- sim_summary %>%
  bind_rows(sim_summary_1) %>%
  bind_rows(sim_summary_3) %>%
  bind_rows(sim_summary_7) %>%
  bind_rows(sim_summary_10) %>%
  bind_rows(sim_summary_20) %>%
  bind_rows(sim_summary_30) %>%
  bind_rows(sim_summary_40) %>%
  bind_rows(sim_summary_50) %>%
  bind_rows(sim_summary_60) %>%
  bind_rows(sim_summary_70) %>%
  bind_rows(sim_summary_80) %>%
  bind_rows(sim_summary_100) %>%
  bind_rows(sim_summary_150) %>%
  bind_rows(sim_summary_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model="single",
         patches = 1)

write_csv(waning_results_single, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_single.csv")

waning_results_single
ggplot(waning_results_single, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

7-Patch Metapopulation Model

Recent studies have suggested that pre-agricultural hunter-gatherers did not live in small isolated groups but fromed interconnected multi-camp networks. To investigate this we built a second population that accounts for metapopulation structure of hunter-gatherers. The second model follows an almost identical format as the single population model, but instead has been expanded to accommodate the metapopulation structure of multi-band hunter-gatherer groups:

\[\begin{align*} \frac{{{\mathrm{d}}S}}{{{\mathrm{d}}t}} & = \underbrace {\mu_i N_i}_{{\mathrm{birth}}}~ - ~\underbrace {\biggl(\frac{\beta_{ii} I_i}{N_i} + \frac{\beta_{ji} I_j} {N_j} + ... \biggr)S_i}_{{\mathrm{infection}}}~~ + \underbrace {\omega_i R_i}_{{\mathrm{lost}}\,{\mathrm{immunity}}} - \underbrace {\mu_i S_i}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}E}}{{{\mathrm{d}}t}} & = \underbrace {\biggl(\frac{\beta_{ii} I_i}{N_i} + \frac{\beta_{ji} I_j} {N_j} + ... \biggr)S_i}_{{\mathrm{infection}}}~ - ~\underbrace {\sigma_i E_i}_{{\mathrm{latency}}} - \underbrace {\mu_i E_i}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}I}}{{{\mathrm{d}}t}} & = \underbrace {\sigma_i E_i}_{{\mathrm{latency}}} - \underbrace {\gamma_i I_i}_{{\mathrm{recovery}}} - ~\underbrace {\left( {\mu_i + \alpha_i } \right)I_i}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}R}}{{{\mathrm{d}}t}} & = \underbrace {\gamma_i I_i}_{{\mathrm{recovery}}} - \underbrace {\omega_i R_i}_{{\mathrm{lost}}\ {\mathrm{immunity}}} - \underbrace {\mu_i R_i}_{{\mathrm{death}}} \end{align*}\]

These coupled differential equations describe the within-patch SEIRS-type dynamics of the \(i\)th patch where the force of infection is driven by contact of susceptibles with infecteds within the \(i\)th patch and in the \(j\)th other patches. Both models assume that compartments are well-mixed and that the waiting times between compartments are exponentially distributed.

Model Set-up

We first modeled transmission in a metapopulation of 7 camps, as observed by Migliano et al. (2023), with one initially infected individual from a randomly selected patch.

# Define Paramenters
patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Patch size
U <- length(patchPopSize)                    # Number of patches
initial_infected <-  as.vector(rmultinom(1, 1, rep(0.5, U)))   # Initial infected (initial infected patch randomly generated)
initial_infected_patch <- which(initial_infected > 0)
simName <- "SIRS metapopulation model"       # Simulation name
tf <- 365*3                                   # Final time

# Agta Hunter-Gatherer contact rates
within_pop_contact = 1
between_pop_contact = 0.5/U     # normalised by number of patches 

#Create the named initial state vector for the U-patch system.

x0_meta <- unlist(lapply(
  seq_len(U), 
  function(i){ 
    c(patchPopSize[i] - initial_infected[i], initial_infected[i], 0, 0, patchPopSize[i])
  }
))

names(x0_meta) <- unlist(lapply(seq_len(U), function(i) paste0(c("S","E","I", "R", "N"), i)))


# Define the state change matrix for a single patch
nu_meta <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                     +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                      0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                      0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                      0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
# Mass-action
a_meta <-
  unlist(lapply(
    seq_len(U),
    function(patch) {
      i <- patch
      patches <- 1:U
      #j <- if (patch == 1) U else patch - 1
      other_patches <- patches[-i]
      patch_beta <- c()
      for(k in (1:(U-1))){
        patch_beta[k] = paste0("+(beta_", other_patches[k],i, "*I", other_patches[k], "/N", other_patches[k], ")*S", i)
      }
      c(
        paste0("(beta_", i, i, "*I", i,"/N", i, ")*S",i, paste0(patch_beta, collapse="")), # Infection
        paste0("sigma*E", i),                                       # Becomes infecious
        paste0("gamma*I", i),                                       # Recovery from infection
        paste0("omega*R", i),       # Loss of immunity
        paste0("mu*N", i),                             # Births
        paste0("mu*S", i),                                             # Deaths (S)
        paste0("mu*E", i),                                             # Deaths (E)
        paste0("mu*I", i),                                             # Deaths (I)
        paste0("mu*R", i),                                             # Deaths (R)
        paste0("alpha*I", i)                                           # Deaths from infection
        
      )
    }
  ))

Define functions for calculating R0 from next-generation matrix

# Calculate R0 from NGM

R0ngm <- function(nextgen_matrix) {
  eigenvalues = eigen(nextgen_matrix, only.values = T)
  R0 = max(abs(eigenvalues$values))
  return(R0)
}

beta.ngm <- function(beta_matrix) {
  eigenvalues = eigen(beta_matrix, only.values = T)
  beta_ngm = max(abs(eigenvalues$values))
  return(beta_ngm)
}

Run Metapopulation Model

#Collect parameters
parms_meta <- list(
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

# Define transmission terms and populate next-generation matrix
beta <- 0.6

nextgen_matrix <- matrix(nrow = U, ncol = U, data = 0)
beta_matrix <- matrix(nrow = U, ncol = U, data = 0)


for(i in 1:U){
  for(j in 1:U){
    parms_meta[[paste0("beta_",i,i)]] = within_pop_contact*beta
    nextgen_matrix[i,i] = within_pop_contact*beta*(1/parms_meta$gamma)
    parms_meta[[paste0("beta_",j,i)]] = between_pop_contact*beta
    nextgen_matrix[j,i] = between_pop_contact*beta*(1/parms_meta$gamma)
    nextgen_matrix[i,j] = between_pop_contact*beta*(1/parms_meta$gamma)
    parms_meta[[paste0("beta_",j,j)]] = within_pop_contact*beta
    nextgen_matrix[j,j] = within_pop_contact*beta*(1/parms_meta$gamma)
    beta_matrix[i,i] = within_pop_contact*beta
    beta_matrix[j,i] = between_pop_contact*beta
    beta_matrix[i,j] = between_pop_contact*beta
    beta_matrix[j,j] = within_pop_contact*beta
  }
  parms_meta[[paste0("N", i)]] = patchPopSize[i]
}
# Run simulations with the Direct method
set.seed(25)
out_meta <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Plot
plot_data_meta <- out_meta$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta <- ggplot(data = plot_data_meta, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 1, scales = "free_y")+
  labs(x="Time (Days)",
       y="Number of Individuals",
       colour="State")+
  theme_bw()
plot_meta

ggsave(filename = "meta_plot_7.pdf", 
       plot = plot_meta,
       device = "pdf",
       width = 7, 
       height = 8,
       path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
## Table showing extinction/transmission info for each patch

extinct_data_meta <- out_meta$data %>%
  as_tibble() %>%
  slice_max(t) %>%
  distinct() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N")),
         persist = case_when(state=="I" & count > 0 ~ T, 
                             state=="I" & count == 0 ~ F)) %>%
  drop_na() %>%
  select(patch, count, persist)
extinct_data_meta
beta_meta <- beta.ngm(beta_matrix)
paste0("Beta for whole system = ", beta_meta)


R0_meta <- R0ngm(nextgen_matrix)
paste0("R0 = ", R0_meta)


paste0("Actual number of infecteds at end of sim = ", sum(extinct_data_meta$count))
 # Total number of infecteds at the end of sim across all patches

sim_endpoint_meta <- as_tibble(out_meta$data) %>%
  slice_max(t) %>%
  distinct()


paste0("Did simulation run reach final endpoint?")
if (sim_endpoint_meta$t >= tf) {
  print("Yes")
} else {
  print("No")}
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta <- list()
sim_list_meta <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(lapply(
  seq_len(U), 
  function(x){ 
    c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
  }
))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))
  
  out_100_meta <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta <- out_100_meta$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta[[i]] <- sim_data_meta
}

sim_output_meta <- bind_rows(sim_list_meta)
# Summary table of endpoint data
sim_output_meta <- sim_output_meta %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta
# Make Summary Table of output
sim_summary_meta <- sim_output_meta %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_meta

Varying waining immunity

0 Days

#Collect parameters
parms_meta_0 <- parms_meta
parms_meta_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_meta_0 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_0 <- out_meta_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_0 <- ggplot(data = plot_data_meta_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_0
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_0 <- list()
sim_list_meta_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_0 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_0 <- out_100_meta_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_0[[i]] <- sim_data_meta_0
}

sim_output_meta_0 <- bind_rows(sim_list_meta_0)
# Summary table of endpoint data
sim_output_meta_0 <- sim_output_meta_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_0

# Make Summary Table of output
sim_summary_meta_0 <- sim_output_meta_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_meta_0

1 Day

#Collect parameters
parms_meta_1 <- parms_meta
parms_meta_1$omega <- 1


# Run simulations with the Direct method
set.seed(4)
out_meta_1 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_1,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_1 <- out_meta_1$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_1 <- ggplot(data = plot_data_meta_1, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_1
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_1 <- list()
sim_list_meta_1 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_1 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_1 <- out_100_meta_1$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_1[[i]] <- sim_data_meta_1
}

sim_output_meta_1 <- bind_rows(sim_list_meta_1)
# Summary table of endpoint data
sim_output_meta_1 <- sim_output_meta_1 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_1

# Make Summary Table of output
sim_summary_meta_1 <- sim_output_meta_1 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_meta_1

3 Days

#Collect parameters
parms_meta_3 <- parms_meta
parms_meta_3$omega <- 1/3


# Run simulations with the Direct method
set.seed(4)
out_meta_3 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_3,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_3 <- out_meta_3$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_3 <- ggplot(data = plot_data_meta_3, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_3
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_3 <- list()
sim_list_meta_3 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_3 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_3 <- out_100_meta_3$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_3[[i]] <- sim_data_meta_3
}

sim_output_meta_3 <- bind_rows(sim_list_meta_3)
# Summary table of endpoint data
sim_output_meta_3 <- sim_output_meta_3 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_3

# Make Summary Table of output
sim_summary_meta_3 <- sim_output_meta_3 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_meta_3

7 Days

#Collect parameters
parms_meta_7 <- parms_meta
parms_meta_7$omega <- 1/7


# Run simulations with the Direct method
set.seed(4)
out_meta_7 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_7,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_7 <- out_meta_7$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_7 <- ggplot(data = plot_data_meta_7, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_7
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_7 <- list()
sim_list_meta_7 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_7 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_7 <- out_100_meta_7$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_7[[i]] <- sim_data_meta_7
}

sim_output_meta_7 <- bind_rows(sim_list_meta_7)
# Summary table of endpoint data
sim_output_meta_7 <- sim_output_meta_7 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_7

# Make Summary Table of output
sim_summary_meta_7 <- sim_output_meta_7 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_meta_7

10 Days

#Collect parameters
parms_meta_10 <- parms_meta
parms_meta_10$omega <- 1/10

# Run simulations with the Direct method
set.seed(4)
out_meta_10 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_10 <- out_meta_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_10 <- ggplot(data = plot_data_meta_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_10
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_10 <- list()
sim_list_meta_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_10 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_10 <- out_100_meta_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_10[[i]] <- sim_data_meta_10
}

sim_output_meta_10 <- bind_rows(sim_list_meta_10)
# Summary table of endpoint data
sim_output_meta_10 <- sim_output_meta_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))

# Make Summary Table of output
sim_summary_meta_10 <- sim_output_meta_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/14)
sim_summary_meta_10

20 Days

#Collect parameters
parms_meta_20 <- parms_meta
parms_meta_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_meta_20 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_20 <- out_meta_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_20 <- ggplot(data = plot_data_meta_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_20
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_20 <- list()
sim_list_meta_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_20 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_20 <- out_100_meta_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_20[[i]] <- sim_data_meta_20
}

sim_output_meta_20 <- bind_rows(sim_list_meta_20)
# Summary table of endpoint data
sim_output_meta_20 <- sim_output_meta_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_20

# Make Summary Table of output
sim_summary_meta_20 <- sim_output_meta_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_meta_20

30 Days

#Collect parameters
parms_meta_30 <- parms_meta
parms_meta_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_meta_30 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_30 <- out_meta_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_30 <- ggplot(data = plot_data_meta_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_30
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_30 <- list()
sim_list_meta_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_30 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_30 <- out_100_meta_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_30[[i]] <- sim_data_meta_30
}

sim_output_meta_30 <- bind_rows(sim_list_meta_30)
# Summary table of endpoint data
sim_output_meta_30 <- sim_output_meta_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_30

# Make Summary Table of output
sim_summary_meta_30 <- sim_output_meta_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_meta_30

40 Days

#Collect parameters
parms_meta_40 <- parms_meta
parms_meta_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_meta_40 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_40 <- out_meta_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_40 <- ggplot(data = plot_data_meta_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_40
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_40 <- list()
sim_list_meta_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_40 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_40 <- out_100_meta_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_40[[i]] <- sim_data_meta_40
}

sim_output_meta_40 <- bind_rows(sim_list_meta_40)
# Summary table of endpoint data
sim_output_meta_40 <- sim_output_meta_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_40

# Make Summary Table of output
sim_summary_meta_40 <- sim_output_meta_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_meta_40

50 Days

#Collect parameters
parms_meta_50 <- parms_meta
parms_meta_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_meta_50 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_50 <- out_meta_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_50 <- ggplot(data = plot_data_meta_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_50
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_50 <- list()
sim_list_meta_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_50 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_50 <- out_100_meta_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_50[[i]] <- sim_data_meta_50
}

sim_output_meta_50 <- bind_rows(sim_list_meta_50)
# Summary table of endpoint data
sim_output_meta_50 <- sim_output_meta_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_50

# Make Summary Table of output
sim_summary_meta_50 <- sim_output_meta_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_meta_50

60 Days

#Collect parameters
parms_meta_60 <- parms_meta
parms_meta_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_meta_60 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_60 <- out_meta_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_60 <- ggplot(data = plot_data_meta_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_60
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_60 <- list()
sim_list_meta_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_60 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_60 <- out_100_meta_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_60[[i]] <- sim_data_meta_60
}

sim_output_meta_60 <- bind_rows(sim_list_meta_60)
# Summary table of endpoint data
sim_output_meta_60 <- sim_output_meta_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_60

# Make Summary Table of output
sim_summary_meta_60 <- sim_output_meta_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_meta_60

70 Days

#Collect parameters
parms_meta_70 <- parms_meta
parms_meta_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_meta_70 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_70 <- out_meta_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_70 <- ggplot(data = plot_data_meta_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_70
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_70 <- list()
sim_list_meta_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_70 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_70 <- out_100_meta_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_70[[i]] <- sim_data_meta_70
}

sim_output_meta_70 <- bind_rows(sim_list_meta_70)
# Summary table of endpoint data
sim_output_meta_70 <- sim_output_meta_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_70

# Make Summary Table of output
sim_summary_meta_70 <- sim_output_meta_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_meta_70

80 Days

#Collect parameters
parms_meta_80 <- parms_meta
parms_meta_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_meta_80 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_80 <- out_meta_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_80 <- ggplot(data = plot_data_meta_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_80
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_80 <- list()
sim_list_meta_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_80 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_80 <- out_100_meta_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_80[[i]] <- sim_data_meta_80
}

sim_output_meta_80 <- bind_rows(sim_list_meta_80)
# Summary table of endpoint data
sim_output_meta_80 <- sim_output_meta_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_80

# Make Summary Table of output
sim_summary_meta_80 <- sim_output_meta_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_meta_80

90 Days

#Collect parameters
parms_meta_90 <- parms_meta
parms_meta_90$omega <- 1/90


# Run simulations with the Direct method
set.seed(4)
out_meta_90 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_90,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_90 <- out_meta_90$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_90 <- ggplot(data = plot_data_meta_90, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_90
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_90 <- list()
sim_list_meta_90 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_90 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_90 <- out_100_meta_90$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_90[[i]] <- sim_data_meta_90
}

sim_output_meta_90 <- bind_rows(sim_list_meta_90)
# Summary table of endpoint data
sim_output_meta_90 <- sim_output_meta_90 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_90

# Make Summary Table of output
sim_summary_meta_90 <- sim_output_meta_90 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_meta_90

180 Days

#Collect parameters
parms_meta_180 <- parms_meta
parms_meta_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(20)
out_meta_180 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_180 <- out_meta_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_180 <- ggplot(data = plot_data_meta_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_180
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_180 <- list()
sim_list_meta_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_180 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_180 <- out_100_meta_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_180[[i]] <- sim_data_meta_180
}

sim_output_meta_180 <- bind_rows(sim_list_meta_180)
# Summary table of endpoint data
sim_output_meta_180 <- sim_output_meta_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_180

# Make Summary Table of output
sim_summary_meta_180 <- sim_output_meta_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_meta_180

110 Days

#Collect parameters
parms_meta_110 <- parms_meta
parms_meta_110$omega <- 1/110


# Run simulations with the Direct method
set.seed(4)
out_meta_110 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_110,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_110 <- out_meta_110$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_110 <- ggplot(data = plot_data_meta_110, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_110
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_110 <- list()
sim_list_meta_110 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_110 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_110 <- out_100_meta_110$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_110[[i]] <- sim_data_meta_110
}

sim_output_meta_110 <- bind_rows(sim_list_meta_110)
# Summary table of endpoint data
sim_output_meta_110 <- sim_output_meta_110 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_110

# Make Summary Table of output
sim_summary_meta_110 <- sim_output_meta_110 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_meta_110

120 Days

#Collect parameters
parms_meta_120 <- parms_meta
parms_meta_120$omega <- 1/120


# Run simulations with the Direct method
set.seed(4)
out_meta_120 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_120,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_120 <- out_meta_120$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_120 <- ggplot(data = plot_data_meta_120, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_120
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_120 <- list()
sim_list_meta_120 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_120 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_120 <- out_100_meta_120$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_120[[i]] <- sim_data_meta_120
}

sim_output_meta_120 <- bind_rows(sim_list_meta_120)
# Summary table of endpoint data
sim_output_meta_120 <- sim_output_meta_120 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_120

# Make Summary Table of output
sim_summary_meta_120 <- sim_output_meta_120 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_meta_120

130 Days

#Collect parameters
parms_meta_130 <- parms_meta
parms_meta_130$omega <- 1/130


# Run simulations with the Direct method
set.seed(4)
out_meta_130 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_130,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_130 <- out_meta_130$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_130 <- ggplot(data = plot_data_meta_130, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_130
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_130 <- list()
sim_list_meta_130 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_130 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_130 <- out_100_meta_130$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_130[[i]] <- sim_data_meta_130
}

sim_output_meta_130 <- bind_rows(sim_list_meta_130)
# Summary table of endpoint data
sim_output_meta_130 <- sim_output_meta_130 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_130

# Make Summary Table of output
sim_summary_meta_130 <- sim_output_meta_130 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_meta_130

150 Days

#Collect parameters
parms_meta_150 <- parms_meta
parms_meta_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_meta_150 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_150 <- out_meta_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_150 <- ggplot(data = plot_data_meta_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_150
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_150 <- list()
sim_list_meta_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_150 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_150 <- out_100_meta_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_150[[i]] <- sim_data_meta_150
}

sim_output_meta_150 <- bind_rows(sim_list_meta_150)
# Summary table of endpoint data
sim_output_meta_150 <- sim_output_meta_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_150

# Make Summary Table of output
sim_summary_meta_150 <- sim_output_meta_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_meta_150

220 Days

#Collect parameters
parms_meta_220 <- parms_meta
parms_meta_220$omega <- 1/220


# Run simulations with the Direct method
set.seed(4)
out_meta_220 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_220,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_220 <- out_meta_220$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_220 <- ggplot(data = plot_data_meta_220, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_220
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_220 <- list()
sim_list_meta_220 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_220 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_220 <- out_100_meta_220$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_220[[i]] <- sim_data_meta_220
}

sim_output_meta_220 <- bind_rows(sim_list_meta_220)
# Summary table of endpoint data
sim_output_meta_220 <- sim_output_meta_220 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_220

# Make Summary Table of output
sim_summary_meta_220 <- sim_output_meta_220 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_meta_220

270 Days

#Collect parameters
parms_meta_270 <- parms_meta
parms_meta_270$omega <- 1/270


# Run simulations with the Direct method
set.seed(4)
out_meta_270 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_270,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_270 <- out_meta_270$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_270 <- ggplot(data = plot_data_meta_270, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_270
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_270 <- list()
sim_list_meta_270 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_270 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_270 <- out_100_meta_270$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_270[[i]] <- sim_data_meta_270
}

sim_output_meta_270 <- bind_rows(sim_list_meta_270)
# Summary table of endpoint data
sim_output_meta_270 <- sim_output_meta_270 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_270

# Make Summary Table of output
sim_summary_meta_270 <- sim_output_meta_270 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_meta_270

365 Days

#Collect parameters
parms_meta_365 <- parms_meta
parms_meta_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_meta_365 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_365 <- out_meta_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_365 <- ggplot(data = plot_data_meta_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_365
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_365 <- list()
sim_list_meta_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_365 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_365 <- out_100_meta_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_365[[i]] <- sim_data_meta_365
}

sim_output_meta_365 <- bind_rows(sim_list_meta_365)
# Summary table of endpoint data
sim_output_meta_365 <- sim_output_meta_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_365

# Make Summary Table of output
sim_summary_meta_365 <- sim_output_meta_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_meta_365

Single

Results

waning_results_7 <- sim_summary_meta %>%
  bind_rows(sim_summary_meta_3) %>%
  bind_rows(sim_summary_meta_7) %>%
  bind_rows(sim_summary_meta_10) %>%
  bind_rows(sim_summary_meta_20) %>%
  bind_rows(sim_summary_meta_30) %>%
  bind_rows(sim_summary_meta_40) %>%
  bind_rows(sim_summary_meta_50) %>%
  bind_rows(sim_summary_meta_60) %>%
  bind_rows(sim_summary_meta_70) %>%
  bind_rows(sim_summary_meta_80) %>%
  bind_rows(sim_summary_meta_90) %>%
  bind_rows(sim_summary_meta_100) %>%
  bind_rows(sim_summary_meta_110) %>%
  bind_rows(sim_summary_meta_120) %>%
  bind_rows(sim_summary_meta_130) %>%
  bind_rows(sim_summary_meta_150) %>%
  bind_rows(sim_summary_meta_220) %>%
  bind_rows(sim_summary_meta_270) %>%
  bind_rows(sim_summary_meta_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model = "meta",
         patches = 7)

write_csv(waning_results_7, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_7.csv")

waning_results_7
ggplot(waning_results_7, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

3-Patch Metapopulation Model

The same metapopulation SEIRS model was then used to model the dynamics of persistence in a 3-patch system and understand the effect of waning immunity.

###Set-up

# Define Paramenters
patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Patch size
U <- length(patchPopSize_3)                    # Number of patches
initial_infected <-  as.vector(rmultinom(1, 1, rep(0.5, U)))   # Initial infected (initial infected patch randomly generated)
initial_infected_patch <- which(initial_infected > 0)
simName <- "SIRS metapopulation model"       # Simulation name
tf <- 365*3                                   # Final time

# Agta Hunter-Gatherer contact rates
within_pop_contact = 1
between_pop_contact = 0.5/U     # normalised by number of patches 

#Create the named initial state vector for the U-patch system.

x0_3_meta <- unlist(lapply(
  seq_len(U), 
  function(i){ 
    c(patchPopSize_3[i] - initial_infected[i], initial_infected[i], 0, 0, patchPopSize_3[i])
  }
))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(i) paste0(c("S","E","I", "R", "N"), i)))


# Define the state change matrix for a single patch
nu_3_meta <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                     +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                      0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                      0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                      0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
# Mass-action
a_3_meta <-
  unlist(lapply(
    seq_len(U),
    function(patch) {
      i <- patch
      patches <- 1:U
      #j <- if (patch == 1) U else patch - 1
      other_patches <- patches[-i]
      patch_beta <- c()
      for(k in (1:(U-1))){
        patch_beta[k] = paste0("+(beta_", other_patches[k],i, "*I", other_patches[k], "/N", other_patches[k], ")*S", i)
      }
      c(
        paste0("(beta_", i, i, "*I", i,"/N", i, ")*S",i, paste0(patch_beta, collapse="")), # Infection
        paste0("sigma*E", i),                                       # Becomes infecious
        paste0("gamma*I", i),                                       # Recovery from infection
        paste0("omega*R", i),       # Loss of immunity
        paste0("mu*N", i),                             # Births
        paste0("mu*S", i),                                             # Deaths (S)
        paste0("mu*E", i),                                             # Deaths (E)
        paste0("mu*I", i),                                             # Deaths (I)
        paste0("mu*R", i),                                             # Deaths (R)
        paste0("alpha*I", i)                                           # Deaths from infection
        
      )
    }
  ))

Run Metapopulation Model

#Collect parameters
parms_3_meta <- list(
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

# Define transmission terms and populate next-generation matrix
beta <- 0.6

nextgen_3_matrix <- matrix(nrow = U, ncol = U, data = 0)
beta_3_matrix <- matrix(nrow = U, ncol = U, data = 0)


for(i in 1:U){
  for(j in 1:U){
    parms_3_meta[[paste0("beta_",i,i)]] = within_pop_contact*beta
    nextgen_3_matrix[i,i] = within_pop_contact*beta*(1/parms_3_meta$gamma)
    parms_3_meta[[paste0("beta_",j,i)]] = between_pop_contact*beta
    nextgen_3_matrix[j,i] = between_pop_contact*beta*(1/parms_3_meta$gamma)
    nextgen_3_matrix[i,j] = between_pop_contact*beta*(1/parms_3_meta$gamma)
    parms_3_meta[[paste0("beta_",j,j)]] = within_pop_contact*beta
    nextgen_3_matrix[j,j] = within_pop_contact*beta*(1/parms_3_meta$gamma)
    beta_3_matrix[i,i] = within_pop_contact*beta
    beta_3_matrix[j,i] = between_pop_contact*beta
    beta_3_matrix[i,j] = between_pop_contact*beta
    beta_3_matrix[j,j] = within_pop_contact*beta
  }
  parms_3_meta[[paste0("N", i)]] = patchPopSize_3[i]
}
# Run simulations with the Direct method
set.seed(25)
out_3_meta <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Plot
plot_data_3_meta <- out_3_meta$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta <- ggplot(data = plot_data_3_meta, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 1, scales = "free_y")+
  labs(x="Time (Days)",
       y="Number of Individuals",
       colour="State")+
  theme_bw()
plot_3_meta

ggsave(filename = "meta_plot_3.pdf", 
       plot = plot_3_meta,
       device = "pdf",
       width = 7, 
       height = 8,
       path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
## Table showing extinction/transmission info for each patch

extinct_data_3_meta <- out_3_meta$data %>%
  as_tibble() %>%
  slice_max(t) %>%
  distinct() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N")),
         persist = case_when(state=="I" & count > 0 ~ T, 
                             state=="I" & count == 0 ~ F)) %>%
  drop_na() %>%
  select(patch, count, persist)
extinct_data_3_meta
beta_3_meta <- beta.ngm(beta_3_matrix)
paste0("Beta for whole system = ", beta_3_meta)


R0_3_meta <- R0ngm(nextgen_3_matrix)
paste0("R0 = ", R0_3_meta)


paste0("Actual number of infecteds at end of sim = ", sum(extinct_data_3_meta$count))
 # Total number of infecteds at the end of sim across all patches

sim_endpoint_3_meta <- as_tibble(out_3_meta$data) %>%
  slice_max(t) %>%
  distinct()


paste0("Did simulation run reach final endpoint?")
if (sim_endpoint_3_meta$t >= tf) {
  print("Yes")
} else {
  print("No")}
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta <- list()
sim_list_3_meta <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(lapply(
  seq_len(U), 
  function(x){ 
    c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
  }
))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))
  
  out_100_3_meta <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta <- out_100_3_meta$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta[[i]] <- sim_data_3_meta
}

sim_output_3_meta <- bind_rows(sim_list_3_meta)
# Summary table of endpoint data
sim_output_3_meta <- sim_output_3_meta %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta
# Make Summary Table of output
sim_summary_3_meta <- sim_output_3_meta %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_3_meta

Varying waining immunity

0 Days

#Collect parameters
parms_3_meta_0 <- parms_3_meta
parms_3_meta_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_3_meta_0 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_0 <- out_3_meta_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_0 <- ggplot(data = plot_data_3_meta_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_0
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_0 <- list()
sim_list_3_meta_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_0 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_0 <- out_100_3_meta_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_0[[i]] <- sim_data_3_meta_0
}

sim_output_3_meta_0 <- bind_rows(sim_list_3_meta_0)
# Summary table of endpoint data
sim_output_3_meta_0 <- sim_output_3_meta_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_0

# Make Summary Table of output
sim_summary_3_meta_0 <- sim_output_3_meta_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_3_meta_0

1 Day

#Collect parameters
parms_3_meta_1 <- parms_3_meta
parms_3_meta_1$omega <- 1


# Run simulations with the Direct method
set.seed(4)
out_3_meta_1 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_1,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_1 <- out_3_meta_1$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_1 <- ggplot(data = plot_data_3_meta_1, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_1
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_1 <- list()
sim_list_3_meta_1 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_1 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_1 <- out_100_3_meta_1$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_1[[i]] <- sim_data_3_meta_1
}

sim_output_3_meta_1 <- bind_rows(sim_list_3_meta_1)
# Summary table of endpoint data
sim_output_3_meta_1 <- sim_output_3_meta_1 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_1

# Make Summary Table of output
sim_summary_3_meta_1 <- sim_output_3_meta_1 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_3_meta_1

3 Days

#Collect parameters
parms_3_meta_3 <- parms_3_meta
parms_3_meta_3$omega <- 1/3


# Run simulations with the Direct method
set.seed(4)
out_3_meta_3 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_3,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_3 <- out_3_meta_3$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_3 <- ggplot(data = plot_data_3_meta_3, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_3
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_3 <- list()
sim_list_3_meta_3 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_3 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_3 <- out_100_3_meta_3$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_3[[i]] <- sim_data_3_meta_3
}

sim_output_3_meta_3 <- bind_rows(sim_list_3_meta_3)
# Summary table of endpoint data
sim_output_3_meta_3 <- sim_output_3_meta_3 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_3

# Make Summary Table of output
sim_summary_3_meta_3 <- sim_output_3_meta_3 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3_meta_3

7 Days

#Collect parameters
parms_3_meta_7 <- parms_3_meta
parms_3_meta_7$omega <- 1/7


# Run simulations with the Direct method
set.seed(4)
out_3_meta_7 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_7,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_7 <- out_3_meta_7$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_7 <- ggplot(data = plot_data_3_meta_7, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_7
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_7 <- list()
sim_list_3_meta_7 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_7 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_7 <- out_100_3_meta_7$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_7[[i]] <- sim_data_3_meta_7
}

sim_output_3_meta_7 <- bind_rows(sim_list_3_meta_7)
# Summary table of endpoint data
sim_output_3_meta_7 <- sim_output_3_meta_7 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_7

# Make Summary Table of output
sim_summary_3_meta_7 <- sim_output_3_meta_7 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_3_meta_7

10 Days

#Collect parameters
parms_3_meta_10 <- parms_3_meta
parms_3_meta_10$omega <- 1/10

# Run simulations with the Direct method
set.seed(4)
out_3_meta_10 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_10 <- out_3_meta_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_10 <- ggplot(data = plot_data_3_meta_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_10
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_10 <- list()
sim_list_3_meta_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_10 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_10 <- out_100_3_meta_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_10[[i]] <- sim_data_3_meta_10
}

sim_output_3_meta_10 <- bind_rows(sim_list_3_meta_10)
# Summary table of endpoint data
sim_output_3_meta_10 <- sim_output_3_meta_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))

# Make Summary Table of output
sim_summary_3_meta_10 <- sim_output_3_meta_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/14)
sim_summary_3_meta_10

20 Days

#Collect parameters
parms_3_meta_20 <- parms_3_meta
parms_3_meta_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_3_meta_20 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_20 <- out_3_meta_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_20 <- ggplot(data = plot_data_3_meta_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_20
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_20 <- list()
sim_list_3_meta_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_20 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_20 <- out_100_3_meta_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_20[[i]] <- sim_data_3_meta_20
}

sim_output_3_meta_20 <- bind_rows(sim_list_3_meta_20)
# Summary table of endpoint data
sim_output_3_meta_20 <- sim_output_3_meta_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_20

# Make Summary Table of output
sim_summary_3_meta_20 <- sim_output_3_meta_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_3_meta_20

30 Days

#Collect parameters
parms_3_meta_30 <- parms_3_meta
parms_3_meta_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_3_meta_30 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_30 <- out_3_meta_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_30 <- ggplot(data = plot_data_3_meta_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_30
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_30 <- list()
sim_list_3_meta_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_30 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_30 <- out_100_3_meta_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_30[[i]] <- sim_data_3_meta_30
}

sim_output_3_meta_30 <- bind_rows(sim_list_3_meta_30)
# Summary table of endpoint data
sim_output_3_meta_30 <- sim_output_3_meta_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_30

# Make Summary Table of output
sim_summary_3_meta_30 <- sim_output_3_meta_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_3_meta_30

40 Days

#Collect parameters
parms_3_meta_40 <- parms_3_meta
parms_3_meta_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_3_meta_40 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_40 <- out_3_meta_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_40 <- ggplot(data = plot_data_3_meta_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_40
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_40 <- list()
sim_list_3_meta_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_40 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_40 <- out_100_3_meta_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_40[[i]] <- sim_data_3_meta_40
}

sim_output_3_meta_40 <- bind_rows(sim_list_3_meta_40)
# Summary table of endpoint data
sim_output_3_meta_40 <- sim_output_3_meta_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_40

# Make Summary Table of output
sim_summary_3_meta_40 <- sim_output_3_meta_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_3_meta_40

50 Days

#Collect parameters
parms_3_meta_50 <- parms_3_meta
parms_3_meta_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_3_meta_50 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_50 <- out_3_meta_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_50 <- ggplot(data = plot_data_3_meta_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_50
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_50 <- list()
sim_list_3_meta_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_50 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_50 <- out_100_3_meta_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_50[[i]] <- sim_data_3_meta_50
}

sim_output_3_meta_50 <- bind_rows(sim_list_3_meta_50)
# Summary table of endpoint data
sim_output_3_meta_50 <- sim_output_3_meta_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_50

# Make Summary Table of output
sim_summary_3_meta_50 <- sim_output_3_meta_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_3_meta_50

60 Days

#Collect parameters
parms_3_meta_60 <- parms_3_meta
parms_3_meta_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_3_meta_60 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_60 <- out_3_meta_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_60 <- ggplot(data = plot_data_3_meta_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_60
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_60 <- list()
sim_list_3_meta_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_60 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_60 <- out_100_3_meta_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_60[[i]] <- sim_data_3_meta_60
}

sim_output_3_meta_60 <- bind_rows(sim_list_3_meta_60)
# Summary table of endpoint data
sim_output_3_meta_60 <- sim_output_3_meta_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_60

# Make Summary Table of output
sim_summary_3_meta_60 <- sim_output_3_meta_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_3_meta_60

70 Days

#Collect parameters
parms_3_meta_70 <- parms_3_meta
parms_3_meta_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_3_meta_70 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_70 <- out_3_meta_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_70 <- ggplot(data = plot_data_3_meta_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_70
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_70 <- list()
sim_list_3_meta_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_70 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_70 <- out_100_3_meta_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_70[[i]] <- sim_data_3_meta_70
}

sim_output_3_meta_70 <- bind_rows(sim_list_3_meta_70)
# Summary table of endpoint data
sim_output_3_meta_70 <- sim_output_3_meta_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_70

# Make Summary Table of output
sim_summary_3_meta_70 <- sim_output_3_meta_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_3_meta_70

80 Days

#Collect parameters
parms_3_meta_80 <- parms_3_meta
parms_3_meta_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_3_meta_80 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_80 <- out_3_meta_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_80 <- ggplot(data = plot_data_3_meta_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_80
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_80 <- list()
sim_list_3_meta_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_80 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_80 <- out_100_3_meta_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_80[[i]] <- sim_data_3_meta_80
}

sim_output_3_meta_80 <- bind_rows(sim_list_3_meta_80)
# Summary table of endpoint data
sim_output_3_meta_80 <- sim_output_3_meta_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_80

# Make Summary Table of output
sim_summary_3_meta_80 <- sim_output_3_meta_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_3_meta_80

90 Days

#Collect parameters
parms_3_meta_90 <- parms_3_meta
parms_3_meta_90$omega <- 1/90


# Run simulations with the Direct method
set.seed(4)
out_3_meta_90 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_90,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_90 <- out_3_meta_90$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_90 <- ggplot(data = plot_data_3_meta_90, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_90
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_90 <- list()
sim_list_3_meta_90 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_90 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_90 <- out_100_3_meta_90$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_90[[i]] <- sim_data_3_meta_90
}

sim_output_3_meta_90 <- bind_rows(sim_list_3_meta_90)
# Summary table of endpoint data
sim_output_3_meta_90 <- sim_output_3_meta_90 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_90

# Make Summary Table of output
sim_summary_3_meta_90 <- sim_output_3_meta_90 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_3_meta_90

180 Days

#Collect parameters
parms_3_meta_180 <- parms_3_meta
parms_3_meta_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(20)
out_3_meta_180 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_180 <- out_3_meta_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_180 <- ggplot(data = plot_data_3_meta_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_180
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_180 <- list()
sim_list_3_meta_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_180 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_180 <- out_100_3_meta_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_180[[i]] <- sim_data_3_meta_180
}

sim_output_3_meta_180 <- bind_rows(sim_list_3_meta_180)
# Summary table of endpoint data
sim_output_3_meta_180 <- sim_output_3_meta_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_180

# Make Summary Table of output
sim_summary_3_meta_180 <- sim_output_3_meta_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_3_meta_180

110 Days

#Collect parameters
parms_3_meta_110 <- parms_3_meta
parms_3_meta_110$omega <- 1/110


# Run simulations with the Direct method
set.seed(4)
out_3_meta_110 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_110,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_110 <- out_3_meta_110$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_110 <- ggplot(data = plot_data_3_meta_110, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_110
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_110 <- list()
sim_list_3_meta_110 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_110 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_110 <- out_100_3_meta_110$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_110[[i]] <- sim_data_3_meta_110
}

sim_output_3_meta_110 <- bind_rows(sim_list_3_meta_110)
# Summary table of endpoint data
sim_output_3_meta_110 <- sim_output_3_meta_110 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_110

# Make Summary Table of output
sim_summary_3_meta_110 <- sim_output_3_meta_110 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_3_meta_110

120 Days

#Collect parameters
parms_3_meta_120 <- parms_3_meta
parms_3_meta_120$omega <- 1/120


# Run simulations with the Direct method
set.seed(4)
out_3_meta_120 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_120,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_120 <- out_3_meta_120$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_120 <- ggplot(data = plot_data_3_meta_120, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_120
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_120 <- list()
sim_list_3_meta_120 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_120 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_120 <- out_100_3_meta_120$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_120[[i]] <- sim_data_3_meta_120
}

sim_output_3_meta_120 <- bind_rows(sim_list_3_meta_120)
# Summary table of endpoint data
sim_output_3_meta_120 <- sim_output_3_meta_120 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_120

# Make Summary Table of output
sim_summary_3_meta_120 <- sim_output_3_meta_120 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_3_meta_120

130 Days

#Collect parameters
parms_3_meta_130 <- parms_3_meta
parms_3_meta_130$omega <- 1/130


# Run simulations with the Direct method
set.seed(4)
out_3_meta_130 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_130,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_130 <- out_3_meta_130$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_130 <- ggplot(data = plot_data_3_meta_130, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_130
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_130 <- list()
sim_list_3_meta_130 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_130 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_130 <- out_100_3_meta_130$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_130[[i]] <- sim_data_3_meta_130
}

sim_output_3_meta_130 <- bind_rows(sim_list_3_meta_130)
# Summary table of endpoint data
sim_output_3_meta_130 <- sim_output_3_meta_130 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_130

# Make Summary Table of output
sim_summary_3_meta_130 <- sim_output_3_meta_130 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_3_meta_130

150 Days

#Collect parameters
parms_3_meta_150 <- parms_3_meta
parms_3_meta_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_3_meta_150 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_150 <- out_3_meta_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_150 <- ggplot(data = plot_data_3_meta_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_150
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_150 <- list()
sim_list_3_meta_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_150 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_150 <- out_100_3_meta_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_150[[i]] <- sim_data_3_meta_150
}

sim_output_3_meta_150 <- bind_rows(sim_list_3_meta_150)
# Summary table of endpoint data
sim_output_3_meta_150 <- sim_output_3_meta_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_150

# Make Summary Table of output
sim_summary_3_meta_150 <- sim_output_3_meta_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_3_meta_150

220 Days

#Collect parameters
parms_3_meta_220 <- parms_3_meta
parms_3_meta_220$omega <- 1/220


# Run simulations with the Direct method
set.seed(4)
out_3_meta_220 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_220,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_220 <- out_3_meta_220$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_220 <- ggplot(data = plot_data_3_meta_220, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_220
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_220 <- list()
sim_list_3_meta_220 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_220 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_220 <- out_100_3_meta_220$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_220[[i]] <- sim_data_3_meta_220
}

sim_output_3_meta_220 <- bind_rows(sim_list_3_meta_220)
# Summary table of endpoint data
sim_output_3_meta_220 <- sim_output_3_meta_220 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_220

# Make Summary Table of output
sim_summary_3_meta_220 <- sim_output_3_meta_220 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_3_meta_220

270 Days

#Collect parameters
parms_3_meta_270 <- parms_3_meta
parms_3_meta_270$omega <- 1/270


# Run simulations with the Direct method
set.seed(4)
out_3_meta_270 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_270,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_270 <- out_3_meta_270$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_270 <- ggplot(data = plot_data_3_meta_270, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_270
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_270 <- list()
sim_list_3_meta_270 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_270 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_270 <- out_100_3_meta_270$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_270[[i]] <- sim_data_3_meta_270
}

sim_output_3_meta_270 <- bind_rows(sim_list_3_meta_270)
# Summary table of endpoint data
sim_output_3_meta_270 <- sim_output_3_meta_270 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_270

# Make Summary Table of output
sim_summary_3_meta_270 <- sim_output_3_meta_270 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_3_meta_270

365 Days

#Collect parameters
parms_3_meta_365 <- parms_3_meta
parms_3_meta_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_3_meta_365 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_365 <- out_3_meta_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_365 <- ggplot(data = plot_data_3_meta_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_365
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_365 <- list()
sim_list_3_meta_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_365 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_365 <- out_100_3_meta_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_365[[i]] <- sim_data_3_meta_365
}

sim_output_3_meta_365 <- bind_rows(sim_list_3_meta_365)
# Summary table of endpoint data
sim_output_3_meta_365 <- sim_output_3_meta_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_365

# Make Summary Table of output
sim_summary_3_meta_365 <- sim_output_3_meta_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_3_meta_365

Single

Results

waning_results_3 <- sim_summary_3_meta %>%
  bind_rows(sim_summary_3_meta_3) %>%
  bind_rows(sim_summary_3_meta_7) %>%
  bind_rows(sim_summary_3_meta_10) %>%
  bind_rows(sim_summary_3_meta_20) %>%
  bind_rows(sim_summary_3_meta_30) %>%
  bind_rows(sim_summary_3_meta_40) %>%
  bind_rows(sim_summary_3_meta_50) %>%
  bind_rows(sim_summary_3_meta_60) %>%
  bind_rows(sim_summary_3_meta_70) %>%
  bind_rows(sim_summary_3_meta_80) %>%
  bind_rows(sim_summary_3_meta_90) %>%
  bind_rows(sim_summary_3_meta_180) %>%
  bind_rows(sim_summary_3_meta_110) %>%
  bind_rows(sim_summary_3_meta_120) %>%
  bind_rows(sim_summary_3_meta_130) %>%
  bind_rows(sim_summary_3_meta_150) %>%
  bind_rows(sim_summary_3_meta_220) %>%
  bind_rows(sim_summary_3_meta_270) %>%
  bind_rows(sim_summary_3_meta_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model = "meta",
         patches = 3)

write_csv(waning_results_3, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_3.csv")

waning_results_3
ggplot(waning_results_3, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

14 Metapopulation Model

The same metapopulation SEIRS model was then used to model the dynamics of persistence in a 14-patch system and understand the effect of waning immunity.

###Set-up

# Define Paramenters
patchPopSize_14 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Patch size
U <- length(patchPopSize_14)                    # Number of patches
initial_infected <-  as.vector(rmultinom(1, 1, rep(0.5, U)))   # Initial infected (initial infected patch randomly generated)
initial_infected_patch <- which(initial_infected > 0)
simName <- "SIRS metapopulation model"       # Simulation name
tf <- 365*3                                   # Final time

# Agta Hunter-Gatherer contact rates
within_pop_contact = 1
between_pop_contact = 0.5/U     # normalised by number of patches 

#Create the named initial state vector for the U-patch system.

x0_14_meta <- unlist(lapply(
  seq_len(U), 
  function(i){ 
    c(patchPopSize_14[i] - initial_infected[i], initial_infected[i], 0, 0, patchPopSize_14[i])
  }
))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(i) paste0(c("S","E","I", "R", "N"), i)))


# Define the state change matrix for a single patch
nu_14_meta <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                     +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                      0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                      0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                      0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
# Mass-action
a_14_meta <-
  unlist(lapply(
    seq_len(U),
    function(patch) {
      i <- patch
      patches <- 1:U
      #j <- if (patch == 1) U else patch - 1
      other_patches <- patches[-i]
      patch_beta <- c()
      for(k in (1:(U-1))){
        patch_beta[k] = paste0("+(beta_", other_patches[k],i, "*I", other_patches[k], "/N", other_patches[k], ")*S", i)
      }
      c(
        paste0("(beta_", i, i, "*I", i,"/N", i, ")*S",i, paste0(patch_beta, collapse="")), # Infection
        paste0("sigma*E", i),                                       # Becomes infecious
        paste0("gamma*I", i),                                       # Recovery from infection
        paste0("omega*R", i),       # Loss of immunity
        paste0("mu*N", i),                             # Births
        paste0("mu*S", i),                                             # Deaths (S)
        paste0("mu*E", i),                                             # Deaths (E)
        paste0("mu*I", i),                                             # Deaths (I)
        paste0("mu*R", i),                                             # Deaths (R)
        paste0("alpha*I", i)                                           # Deaths from infection
        
      )
    }
  ))

Run Metapopulation Model

#Collect parameters
parms_14_meta <- list(
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

# Define transmission terms and populate next-generation matrix
beta <- 0.6

nextgen_14_matrix <- matrix(nrow = U, ncol = U, data = 0)
beta_14_matrix <- matrix(nrow = U, ncol = U, data = 0)


for(i in 1:U){
  for(j in 1:U){
    parms_14_meta[[paste0("beta_",i,i)]] = within_pop_contact*beta
    nextgen_14_matrix[i,i] = within_pop_contact*beta*(1/parms_14_meta$gamma)
    parms_14_meta[[paste0("beta_",j,i)]] = between_pop_contact*beta
    nextgen_14_matrix[j,i] = between_pop_contact*beta*(1/parms_14_meta$gamma)
    nextgen_14_matrix[i,j] = between_pop_contact*beta*(1/parms_14_meta$gamma)
    parms_14_meta[[paste0("beta_",j,j)]] = within_pop_contact*beta
    nextgen_14_matrix[j,j] = within_pop_contact*beta*(1/parms_14_meta$gamma)
    beta_14_matrix[i,i] = within_pop_contact*beta
    beta_14_matrix[j,i] = between_pop_contact*beta
    beta_14_matrix[i,j] = between_pop_contact*beta
    beta_14_matrix[j,j] = within_pop_contact*beta
  }
  parms_14_meta[[paste0("N", i)]] = patchPopSize_14[i]
}
# Run simulations with the Direct method
set.seed(25)
out_14_meta <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Plot
plot_data_14_meta <- out_14_meta$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta <- ggplot(data = plot_data_14_meta, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time (Days)",
       y="Number of Individuals",
       colour="State")+
  theme_bw()
plot_14_meta

ggsave(filename = "meta_14_plot.pdf", 
       plot = plot_14_meta,
       device = "pdf",
       width = 7, 
       height = 8,
       path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
## Table showing extinction/transmission info for each patch

extinct_data_14_meta <- out_14_meta$data %>%
  as_tibble() %>%
  slice_max(t) %>%
  distinct() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N")),
         persist = case_when(state=="I" & count > 0 ~ T, 
                             state=="I" & count == 0 ~ F)) %>%
  drop_na() %>%
  select(patch, count, persist)
extinct_data_14_meta
beta_14_meta <- beta.ngm(beta_14_matrix)
paste0("Beta for whole system = ", beta_14_meta)


R0_14_meta <- R0ngm(nextgen_14_matrix)
paste0("R0 = ", R0_14_meta)


paste0("Actual number of infecteds at end of sim = ", sum(extinct_data_14_meta$count))
 # Total number of infecteds at the end of sim across all patches

sim_endpoint_14_meta <- as_tibble(out_14_meta$data) %>%
  slice_max(t) %>%
  distinct()


paste0("Did simulation run reach final endpoint?")
if (sim_endpoint_14_meta$t >= tf) {
  print("Yes")
} else {
  print("No")}
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta <- list()
sim_list_14_meta <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_14 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(lapply(
  seq_len(U), 
  function(x){ 
    c(patchPopSize_14[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_14[x])
  }
))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))
  
  out_100_14_meta <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta <- out_100_14_meta$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta[[i]] <- sim_data_14_meta
}

sim_output_14_meta <- bind_rows(sim_list_14_meta)
# Summary table of endpoint data
sim_output_14_meta <- sim_output_14_meta %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta
# Make Summary Table of output
sim_summary_14_meta <- sim_output_14_meta %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_14_meta

Varying waining immunity

0 Days

#Collect parameters
parms_14_meta_0 <- parms_14_meta
parms_14_meta_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_14_meta_0 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_0 <- out_14_meta_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_0 <- ggplot(data = plot_data_14_meta_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_0
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_0 <- list()
sim_list_14_meta_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_0 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_0 <- out_100_14_meta_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_0[[i]] <- sim_data_14_meta_0
}

sim_output_14_meta_0 <- bind_rows(sim_list_14_meta_0)
# Summary table of endpoint data
sim_output_14_meta_0 <- sim_output_14_meta_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_0

# Make Summary Table of output
sim_summary_14_meta_0 <- sim_output_14_meta_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_14_meta_0

10 Days

#Collect parameters
parms_14_meta_10 <- parms_14_meta
parms_14_meta_10$omega <- 1/10

# Run simulations with the Direct method
set.seed(4)
out_14_meta_10 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_10 <- out_14_meta_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_10 <- ggplot(data = plot_data_14_meta_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_10
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_10 <- list()
sim_list_14_meta_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_10 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_10 <- out_100_14_meta_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_10[[i]] <- sim_data_14_meta_10
}

sim_output_14_meta_10 <- bind_rows(sim_list_14_meta_10)
# Summary table of endpoint data
sim_output_14_meta_10 <- sim_output_14_meta_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))

# Make Summary Table of output
sim_summary_14_meta_10 <- sim_output_14_meta_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_14_meta_10

20 Days

#Collect parameters
parms_14_meta_20 <- parms_14_meta
parms_14_meta_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_14_meta_20 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_20 <- out_14_meta_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_20 <- ggplot(data = plot_data_14_meta_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_20
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_20 <- list()
sim_list_14_meta_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_20 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_20 <- out_100_14_meta_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_20[[i]] <- sim_data_14_meta_20
}

sim_output_14_meta_20 <- bind_rows(sim_list_14_meta_20)
# Summary table of endpoint data
sim_output_14_meta_20 <- sim_output_14_meta_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_20

# Make Summary Table of output
sim_summary_14_meta_20 <- sim_output_14_meta_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_14_meta_20

30 Days

#Collect parameters
parms_14_meta_30 <- parms_14_meta
parms_14_meta_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_14_meta_30 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_30 <- out_14_meta_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_30 <- ggplot(data = plot_data_14_meta_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_30
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_30 <- list()
sim_list_14_meta_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_30 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_30 <- out_100_14_meta_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_30[[i]] <- sim_data_14_meta_30
}

sim_output_14_meta_30 <- bind_rows(sim_list_14_meta_30)
# Summary table of endpoint data
sim_output_14_meta_30 <- sim_output_14_meta_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_30

# Make Summary Table of output
sim_summary_14_meta_30 <- sim_output_14_meta_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_14_meta_30

40 Days

#Collect parameters
parms_14_meta_40 <- parms_14_meta
parms_14_meta_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_14_meta_40 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_40 <- out_14_meta_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_40 <- ggplot(data = plot_data_14_meta_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_40
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_40 <- list()
sim_list_14_meta_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_40 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_40 <- out_100_14_meta_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_40[[i]] <- sim_data_14_meta_40
}

sim_output_14_meta_40 <- bind_rows(sim_list_14_meta_40)
# Summary table of endpoint data
sim_output_14_meta_40 <- sim_output_14_meta_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_40

# Make Summary Table of output
sim_summary_14_meta_40 <- sim_output_14_meta_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_14_meta_40

50 Days

#Collect parameters
parms_14_meta_50 <- parms_14_meta
parms_14_meta_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_14_meta_50 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_50 <- out_14_meta_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_50 <- ggplot(data = plot_data_14_meta_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_50
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_50 <- list()
sim_list_14_meta_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_50 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_50 <- out_100_14_meta_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_50[[i]] <- sim_data_14_meta_50
}

sim_output_14_meta_50 <- bind_rows(sim_list_14_meta_50)
# Summary table of endpoint data
sim_output_14_meta_50 <- sim_output_14_meta_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_50

# Make Summary Table of output
sim_summary_14_meta_50 <- sim_output_14_meta_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_14_meta_50

60 Days

#Collect parameters
parms_14_meta_60 <- parms_14_meta
parms_14_meta_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_14_meta_60 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_60 <- out_14_meta_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_60 <- ggplot(data = plot_data_14_meta_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_60
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_60 <- list()
sim_list_14_meta_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_60 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_60 <- out_100_14_meta_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_60[[i]] <- sim_data_14_meta_60
}

sim_output_14_meta_60 <- bind_rows(sim_list_14_meta_60)
# Summary table of endpoint data
sim_output_14_meta_60 <- sim_output_14_meta_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_60

# Make Summary Table of output
sim_summary_14_meta_60 <- sim_output_14_meta_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_14_meta_60

70 Days

#Collect parameters
parms_14_meta_70 <- parms_14_meta
parms_14_meta_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_14_meta_70 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_70 <- out_14_meta_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_70 <- ggplot(data = plot_data_14_meta_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_70
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_70 <- list()
sim_list_14_meta_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_70 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_70 <- out_100_14_meta_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_70[[i]] <- sim_data_14_meta_70
}

sim_output_14_meta_70 <- bind_rows(sim_list_14_meta_70)
# Summary table of endpoint data
sim_output_14_meta_70 <- sim_output_14_meta_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_70

# Make Summary Table of output
sim_summary_14_meta_70 <- sim_output_14_meta_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_14_meta_70

80 Days

#Collect parameters
parms_14_meta_80 <- parms_14_meta
parms_14_meta_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_14_meta_80 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_80 <- out_14_meta_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_80 <- ggplot(data = plot_data_14_meta_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_80
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_80 <- list()
sim_list_14_meta_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_80 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_80 <- out_100_14_meta_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_80[[i]] <- sim_data_14_meta_80
}

sim_output_14_meta_80 <- bind_rows(sim_list_14_meta_80)
# Summary table of endpoint data
sim_output_14_meta_80 <- sim_output_14_meta_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_80

# Make Summary Table of output
sim_summary_14_meta_80 <- sim_output_14_meta_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_14_meta_80

90 Days

#Collect parameters
parms_14_meta_90 <- parms_14_meta
parms_14_meta_90$omega <- 1/90


# Run simulations with the Direct method
set.seed(4)
out_14_meta_90 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_90,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_90 <- out_14_meta_90$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_90 <- ggplot(data = plot_data_14_meta_90, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_90
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_90 <- list()
sim_list_14_meta_90 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_90 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_90 <- out_100_14_meta_90$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_90[[i]] <- sim_data_14_meta_90
}

sim_output_14_meta_90 <- bind_rows(sim_list_14_meta_90)
# Summary table of endpoint data
sim_output_14_meta_90 <- sim_output_14_meta_90 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_90

# Make Summary Table of output
sim_summary_14_meta_90 <- sim_output_14_meta_90 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_14_meta_90

180 Days

#Collect parameters
parms_14_meta_180 <- parms_14_meta
parms_14_meta_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(20)
out_14_meta_180 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_180 <- out_14_meta_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_180 <- ggplot(data = plot_data_14_meta_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_180
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_180 <- list()
sim_list_14_meta_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_180 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_180 <- out_100_14_meta_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_180[[i]] <- sim_data_14_meta_180
}

sim_output_14_meta_180 <- bind_rows(sim_list_14_meta_180)
# Summary table of endpoint data
sim_output_14_meta_180 <- sim_output_14_meta_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_180

# Make Summary Table of output
sim_summary_14_meta_180 <- sim_output_14_meta_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_14_meta_180

110 Days

#Collect parameters
parms_14_meta_110 <- parms_14_meta
parms_14_meta_110$omega <- 1/110


# Run simulations with the Direct method
set.seed(4)
out_14_meta_110 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_110,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_110 <- out_14_meta_110$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_110 <- ggplot(data = plot_data_14_meta_110, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_110
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_110 <- list()
sim_list_14_meta_110 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_110 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_110 <- out_100_14_meta_110$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_110[[i]] <- sim_data_14_meta_110
}

sim_output_14_meta_110 <- bind_rows(sim_list_14_meta_110)
# Summary table of endpoint data
sim_output_14_meta_110 <- sim_output_14_meta_110 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_110

# Make Summary Table of output
sim_summary_14_meta_110 <- sim_output_14_meta_110 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_14_meta_110

120 Days

#Collect parameters
parms_14_meta_120 <- parms_14_meta
parms_14_meta_120$omega <- 1/120


# Run simulations with the Direct method
set.seed(4)
out_14_meta_120 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_120,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_120 <- out_14_meta_120$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_120 <- ggplot(data = plot_data_14_meta_120, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_120
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_120 <- list()
sim_list_14_meta_120 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_120 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_120 <- out_100_14_meta_120$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_120[[i]] <- sim_data_14_meta_120
}

sim_output_14_meta_120 <- bind_rows(sim_list_14_meta_120)
# Summary table of endpoint data
sim_output_14_meta_120 <- sim_output_14_meta_120 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_120

# Make Summary Table of output
sim_summary_14_meta_120 <- sim_output_14_meta_120 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_14_meta_120

130 Days

#Collect parameters
parms_14_meta_130 <- parms_14_meta
parms_14_meta_130$omega <- 1/130


# Run simulations with the Direct method
set.seed(4)
out_14_meta_130 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_130,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_130 <- out_14_meta_130$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_130 <- ggplot(data = plot_data_14_meta_130, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_130
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_130 <- list()
sim_list_14_meta_130 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_130 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_130 <- out_100_14_meta_130$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_130[[i]] <- sim_data_14_meta_130
}

sim_output_14_meta_130 <- bind_rows(sim_list_14_meta_130)
# Summary table of endpoint data
sim_output_14_meta_130 <- sim_output_14_meta_130 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_130

# Make Summary Table of output
sim_summary_14_meta_130 <- sim_output_14_meta_130 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_14_meta_130

150 Days

#Collect parameters
parms_14_meta_150 <- parms_14_meta
parms_14_meta_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_14_meta_150 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_150 <- out_14_meta_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_150 <- ggplot(data = plot_data_14_meta_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_150
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_150 <- list()
sim_list_14_meta_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_150 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_150 <- out_100_14_meta_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_150[[i]] <- sim_data_14_meta_150
}

sim_output_14_meta_150 <- bind_rows(sim_list_14_meta_150)
# Summary table of endpoint data
sim_output_14_meta_150 <- sim_output_14_meta_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_150

# Make Summary Table of output
sim_summary_14_meta_150 <- sim_output_14_meta_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_14_meta_150

220 Days

#Collect parameters
parms_14_meta_220 <- parms_14_meta
parms_14_meta_220$omega <- 1/220


# Run simulations with the Direct method
set.seed(4)
out_14_meta_220 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_220,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_220 <- out_14_meta_220$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_220 <- ggplot(data = plot_data_14_meta_220, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_220
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_220 <- list()
sim_list_14_meta_220 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_220 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_220 <- out_100_14_meta_220$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_220[[i]] <- sim_data_14_meta_220
}

sim_output_14_meta_220 <- bind_rows(sim_list_14_meta_220)
# Summary table of endpoint data
sim_output_14_meta_220 <- sim_output_14_meta_220 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_220

# Make Summary Table of output
sim_summary_14_meta_220 <- sim_output_14_meta_220 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_14_meta_220

270 Days

#Collect parameters
parms_14_meta_270 <- parms_14_meta
parms_14_meta_270$omega <- 1/270


# Run simulations with the Direct method
set.seed(4)
out_14_meta_270 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_270,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_270 <- out_14_meta_270$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_270 <- ggplot(data = plot_data_14_meta_270, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_270
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_270 <- list()
sim_list_14_meta_270 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_270 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_270 <- out_100_14_meta_270$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_270[[i]] <- sim_data_14_meta_270
}

sim_output_14_meta_270 <- bind_rows(sim_list_14_meta_270)
# Summary table of endpoint data
sim_output_14_meta_270 <- sim_output_14_meta_270 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_270

# Make Summary Table of output
sim_summary_14_meta_270 <- sim_output_14_meta_270 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_14_meta_270

365 Days

#Collect parameters
parms_14_meta_365 <- parms_14_meta
parms_14_meta_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_14_meta_365 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_365 <- out_14_meta_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_365 <- ggplot(data = plot_data_14_meta_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_365
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_365 <- list()
sim_list_14_meta_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_365 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_365 <- out_100_14_meta_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_365[[i]] <- sim_data_14_meta_365
}

sim_output_14_meta_365 <- bind_rows(sim_list_14_meta_365)
# Summary table of endpoint data
sim_output_14_meta_365 <- sim_output_14_meta_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_365

# Make Summary Table of output
sim_summary_14_meta_365 <- sim_output_14_meta_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_14_meta_365

Results

waning_results_14 <- sim_summary_14_meta %>%
  bind_rows(sim_summary_14_meta_10) %>%
  bind_rows(sim_summary_14_meta_20) %>%
  bind_rows(sim_summary_14_meta_30) %>%
  bind_rows(sim_summary_14_meta_40) %>%
  bind_rows(sim_summary_14_meta_50) %>%
  bind_rows(sim_summary_14_meta_60) %>%
  bind_rows(sim_summary_14_meta_70) %>%
  bind_rows(sim_summary_14_meta_80) %>%
  bind_rows(sim_summary_14_meta_90) %>%
  bind_rows(sim_summary_14_meta_180) %>%
  bind_rows(sim_summary_14_meta_110) %>%
  bind_rows(sim_summary_14_meta_120) %>%
  bind_rows(sim_summary_14_meta_130) %>%
  bind_rows(sim_summary_14_meta_150) %>%
  bind_rows(sim_summary_14_meta_220) %>%
  bind_rows(sim_summary_14_meta_270) %>%
  bind_rows(sim_summary_14_meta_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model = "meta",
         patches = 14)

write_csv(waning_results_14, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_14.csv")

waning_results_14
ggplot(waning_results_14, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

Combined Results

Results from sinale and metapopulation models were comined into one data frame and visualised.

combined_waning <- waning_results %>%
  bind_rows(waning_results_single) %>%
  bind_rows(waning_results_7) %>%
  bind_rows(waning_results_3) %>%
  bind_rows(waning_results_14)

head(combined_waning)


#write_csv(combined_waning, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/combined_waning_results.csv")
combined_plot <- ggplot(combined_waning, aes(immunity_duration, sum_persist, colour = as.factor(patches)))+
  geom_line(alpha=0.7, size=1)+
  geom_point(alpha=0.5, size=2)+
  geom_segment(x = -Inf, y = 50, xend = 141.5, yend = 50, linetype = "dashed", colour = "grey") +
  geom_segment(x = 5, y = 50, xend = 5, yend = -Inf, linetype = "dashed", colour = "grey") +
  geom_segment(x = 42.5, y = 50, xend = 42.5, yend = -Inf, linetype = "dashed", colour = "grey") +
  geom_segment(x = 91.5, y = 50, xend = 91.5, yend = -Inf, linetype = "dashed", colour = "grey") +
  geom_segment(x = 141.5, y = 50, xend = 141.5, yend = -Inf, linetype = "dashed", colour = "grey") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  scale_x_continuous(breaks = seq(0, 360, 50)) +
  labs(x = "Duration of immunity (days)",
       y = "Probability of persistence after 3 years (%)", 
       colour = "No. Patches")+
  scale_color_discrete(type = wes_palettes$Zissou1[2:5],
                       labels = c("1", "3", "7", "14"))+
  theme_bw()

combined_plot

ggsave(filename = "combined_plot_patches.pdf", plot = combined_plot, device = "pdf", width = 7, height = 5, path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
ggplot(combined_waning, aes(immunity_duration, mean_percent_infected, colour = as.factor(patches)))+
  geom_line()+
  geom_point() +
  labs(x = "Duration of immunity",
       y = "Proportion infected at endpoint (%)", 
       colour = "Patches")+
  scale_color_discrete(type = wes_palettes$Zissou1[2:5],
                       labels = c("1", "3", "7", "14"))+
  theme_bw()

References

LS0tCnRpdGxlOiAiTW9kZWxsaW5nIHRoZSBwZXJzaXN0ZW5jZSBvZiBpbmZlY3Rpb3VzIGRpc2Vhc2VzIGluIHByZS1hZ3JpY3VsdHVyYWwgSHVudGVyLWdhdGhlcmVycyIKc3VidGl0bGU6ICJGaW5hbCBBbmFseXNpcyBSZXBvcnQiCmF1dGhvcjogIk1hdHRoZXcgSG95bGUiCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHRydWUKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKICAgIHRoZW1lOiB5ZXRpCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzCi0tLQojIyBTZXQtdXAKYGBge3J9CiMgcm0obGlzdCA9IGxzKCkpCmxpYnJhcnkod2VzYW5kZXJzb24pCmxpYnJhcnkoR2lsbGVzcGllU1NBKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYGBgCgojIyBCYWNrZ3JvdW5kCgpUaGUgdHJhZGl0aW9uYWxseSBoZWxkIGJlbGllZiB0aGF0IG1vc3QgbW9kZXJuIGluZmVjdGlvdXMgZGlzZWFzZXMgZW1lcmdlZCB3aGVuIGh1bWFucyBiZWdhbiBsaXZpbmcgaW4gbGFyZ2VyIGFncmljdWx0dXJhbCBzZXR0bGVtZW50cyBoYXMgYmVlbiBjaGFsbGVuZ2VkIGJ5IHN0dWRpZXMgb2YgbW9kZXJuIGh1bnRlci1nYXRoZXJlcnMuIFRoaXMgc3R1ZHkgd2lsbCBpbnZlc3RpZ2F0ZSB3aGljaCBlbWVyZ2luZyBwYXRob2dlbnMgbWF5IHBlcnNpc3QgaW4gaHVudGVyLWdhdGhlcmVyIGdyb3VwcyBieSBjb25zdHJ1Y3RpbmcgYSBjb21wYXJ0bWVudCBtb2RlbCBvZiBpbmZlY3Rpb3VzIGRpc2Vhc2UgdHJhbnNtaXNzaW9uIHRoYXQgYWNjb3VudHMgZm9yIGRlbW9ncmFwaHkgYW5kIG11bHRpLWJhbmQgc3RydWN0dXJlLiBUaGlzIHN0dWR5IHdpbGwgbG9vayB0byB1bmRlcnN0YW5kIGhvdyB0aGUgY3JpdGljYWwgY29tbXVuaXR5IHNpemUgcmVxdWlyZWQgdG8gc3VzdGFpbiBhbiBvdXRicmVhayBpcyBhZmZlY3RlZCBieSBob3N0IHBvcHVsYXRpb24gZHluYW1pY3MuIFdlIHNob3cgdGhhdCBtZXRhcG9wdWxhdGlvbiBzdHJ1Y3R1cmUgaW5jcmVhc2VzIHRoZSBwcm9iYWJpbGl0eSBvZiBhIHJlc3BpcmF0b3J5IHBhdGhvZ2VuIHdpdGggd2FuaW5nIGltbXVuaXR5IHBlcnNpc3RpbmcgYWZ0ZXIgMyB5ZWFycy4gVGhlIHByb2JhYmlsaXR5IG9mIHBlcnNpc3RlbmNlIGluY3JlYXNlcyB3aXRoIHRoZSBudW1iZXIgb2Ygc3ViLXBvcHVsYXRpb25zIGJ1dCBpcyBsYXJnZWx5IGRldGVybWluZWQgYnkgdGhlIGR1cmF0aW9uIG9mIGltbXVuaXR5LiBVbmRlcnN0YW5kaW5nIHRoZSBvcmlnaW5zIG9mIGluZmVjdGlvdXMgZGlzZWFzZXMgaXMgYW4gaW1wb3J0YW50IGFyZWEgb2YgcmVzZWFyY2ggdGhhdCB3aWxsIGxlYWQgdG8gaW1wcm92ZWQgc3RyYXRlZ2llcyBmb3IgcmVkdWNpbmcgdGhlaXIgZ2xvYmFsIGJ1cmRlbi4KClRoaXMgcmVwb3J0IHdpbGwgY292ZXIgdGhlIGZ1bGwgYW5hbHlzaXMgdW5kZXJ0YWtlbiB0byBnZW5lcmF0ZSB0aGUgcmVzdWx0cyB1c2VkIGluIG15IE1TYyBwcm9qZWN0LiBBIGZ1bGwgZGVzY3JpcHRpb24gb2YgdGhlIHJlc2VhcmNoIHByb2plY3QgYWltcyBhbmQgbWV0aG9kcyBjYW4gYmUgZm91bmQgaW4gdGhlIGZpbmFsIHBhcGVyIGluIHRoZSBbYEh1bnRlcl9HYXRoZXJlcl9tb2RlbHNgXShodHRwczovL2dpdGh1Yi5jb20vbWF0dGhld2hveWxlL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMpIEdpdEh1YiByZXBvc2l0b3J5LiAgU29tZSBjb2RlIHVzZWQgaW4gdGhpcyBwcm9qZWN0IHdhcyBhZGFwdGVkIGZyb20gdGhlIHR1dG9yaWFscyBhdHRhY2hlZCB0byB0aGUgYEdpbGxlc3BpZVNTQWAgcGFja2FnZS4gCgojIyBNb2RlbCBQYXJhbWV0ZXIgZXN0aW1hdGlvbgoKIyMjIEFndGEgSHVudGVyLUdhdGhlcmVyIERlbW9ncmFwaHkKCk1vZGVybi1kYXkgaHVudGVyLWdhdGhlcmVycyBhcmUgb2Z0ZW4gdXNlZCB0byBtYWtlIGluZmVyZW5jZXMgYWJvdXQgcHJlLWFncmljdWx0dXJhbCBodW1hbiBwb3B1bGF0aW9ucy4gVGhpcyBzdHVkeSBtb2RlbGVkIHRoZSBob3N0IHBvcHVsYXRpb24gb24gYSBncm91cCBvZiBpbmRpZ2Vub3VzIGh1bnRlci1nYXRoZXJlcnMgZnJvbSB0aGUgTm9ydGhlcm4gUGhpbGxpcGluZXMga25vd24gYXMgdGhlIEFndGEuIEluZm9ybWF0aW9uIHJlZ2FyZGluZyBiaXJ0aHMsIGRlYXRocyBhbmQgcG9wdWxhdGlvbiBzaXplIHdlcmUgb2J0YWluIGZyb20gYSBzdHVkeSBjb25kdWN0ZWQgYnkgSGVhZGxhbmQgZXQgYWwuLCAoMjAxMSkuIEF1dGhvcnMgY29uZHVjdGVkIGEgY2Vuc3VzLWxpa2Ugc3VydmV5IG9mIHRoZSBBZ3RhIHRoYXQgZm9sbG93ZWQgJFxzaW0kNCwzMDAgaW5kaXZpZHVhbHMgb3ZlciB0aGUgcGVyaW9kIG9mIDE5NTAtMjAxMC4gVGhpcyBkYXRlIHdhcyBmaXJzdCBleHBsb3JlZCB0byB1bmRlcnN0YW5kIEFndGEgZGVtb2dyYXBoeS4KCgpgYGB7cn0KYWd0YV9kZW1vIDwtIHJlYWQuY3N2KCJBZ3RhX0RhdGEvQWd0YVBvcER5bmFtaWNzX0hlYWRsYW5kMjAwNy5jc3YiKQoKZ2dwbG90KGFndGFfZGVtbywgYWVzKHg9WWVhcikpICsKICBnZW9tX2xpbmUoYWVzKHk9UG9wU2l6ZSksIGNvbG91ciA9IHdlc19wYWxldHRlcyREYXJqZWVsaW5nMVsxXSkgKwogIGdlb21fbGluZShhZXMoeT1CaXJ0aHMpLCBjb2xvdXIgPSB3ZXNfcGFsZXR0ZXMkRGFyamVlbGluZzFbMl0pICsKICBnZW9tX2xpbmUoYWVzKHk9RGVhdGhzKSwgY29sb3VyID0gd2VzX3BhbGV0dGVzJERhcmplZWxpbmcxWzNdKSArCiAgdGhlbWVfYncoKQpgYGAKCiMjIyMgUG9wdWxhdGlvbiBTaXplCmBgYHtyfQpoaXN0KGFndGFfZGVtbyRQb3BTaXplKQpzdW1tYXJ5KGFndGFfZGVtbyRQb3BTaXplKQpgYGAKCiMjIyMgQmlydGhzCmBgYHtyfQpoaXN0KGFndGFfZGVtbyRCaXJ0aHMpCnN1bW1hcnkoYWd0YV9kZW1vJEJpcnRocykKYGBgCgojIyMjIERlYXRocwpgYGB7cn0KaGlzdChhZ3RhX2RlbW8kRGVhdGhzKQpzdW1tYXJ5KGFndGFfZGVtbyREZWF0aHMpCmBgYAoKIyMjIyBCaXJ0aC9EZWF0aCByYXRlIHBlciBwZXJzb24gcGVyIGRheQoKQmlydGggcmF0ZSB3YXMgZXN0aW1hdGVkIGZyb20gdGhpcyBkYXRhIGJ5IHRha2luZyB0aGUgbWVhbiBvZiB0aGUgYW5udWFsIG51bWJlciBvZiBiaXJ0aHMgZGl2aWRlZCBieSB0d28gdGltZXMgdGhlIGFubnVhbCBudW1iZXIgb2YgZmVtYWxlcy4gVGhpcyB3YXMgdGhlbiBzY2FsZWQgYXBwcm9wcmlhdGVseSB0byBvYnRhaW4gdGhlIGRhaWx5IG1lYW4gYmlydGggcmF0ZSBwZXIgcGVyc29uLiAKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CmFndGFfZGVtbyA8LSBhZ3RhX2RlbW8gJT4lCiAgbXV0YXRlKEJpcnRoX3JhdGUgPSBCaXJ0aHMvKEZlbWFsZSoyKSwKICAgICAgICAgQmlydGhfcmF0ZV9kYWlseSA9ICgxICsgQmlydGhfcmF0ZSkgXiAoMS8zNjUpIC0gMSwKICAgICAgICAgRGVhdGhfcmF0ZSA9IChEZWF0aHMvUG9wU2l6ZSksCiAgICAgICAgIERlYXRoX3JhdGVfZGFpbHkgPSAoMSArIERlYXRoX3JhdGUpIF4gKDEvMzY1KSAtIDEsCiAgICAgICAgIFBvcENoYW5nZSA9IChkaWZmID0gUG9wU2l6ZSAtIGxhZyhQb3BTaXplLCBkZWZhdWx0ID0gZmlyc3QoUG9wU2l6ZSkpKSwKICAgICAgICAgUG9wQ2hhbmdlX3JhdGUgPSBhYnMoUG9wQ2hhbmdlKS9Qb3BTaXplLAogICAgICAgICBQb3BDaGFuZ2VfcmF0ZV9kYWlseSA9ICgxICsgUG9wQ2hhbmdlX3JhdGUpIF4gKDEvMzY1KSAtIDEpCmhlYWQoYWd0YV9kZW1vKQoKCmhpc3QoYWd0YV9kZW1vJEJpcnRoX3JhdGUpCmhpc3QoYWd0YV9kZW1vJERlYXRoX3JhdGUpCgpnZ3Bsb3QoYWd0YV9kZW1vLCBhZXMoeD1ZZWFyKSkgKwogIGdlb21fbGluZShhZXMoeT1CaXJ0aF9yYXRlKSwgY29sb3VyID0gd2VzX3BhbGV0dGVzJERhcmplZWxpbmcxWzJdKSArCiAgZ2VvbV9saW5lKGFlcyh5PURlYXRoX3JhdGUpLCBjb2xvdXIgPSB3ZXNfcGFsZXR0ZXMkRGFyamVlbGluZzFbM10pICsKICB0aGVtZV9idygpCgpkZW1vX3N1bSA8LSBhZ3RhX2RlbW8gJT4lCiAgc2VsZWN0KFBvcFNpemUsIEJpcnRoX3JhdGUsIEJpcnRoX3JhdGVfZGFpbHksIERlYXRoX3JhdGUsIERlYXRoX3JhdGVfZGFpbHksIFBvcENoYW5nZV9yYXRlLCBQb3BDaGFuZ2VfcmF0ZV9kYWlseSkgJT4lCiAgICBzdW1tYXJpc2UoYWNyb3NzKAogICAgLmNvbHMgPSBpcy5udW1lcmljLCAKICAgIC5mbnMgPSBsaXN0KE1lYW4gPSBtZWFuLCBTRCA9IHNkKSwgbmEucm0gPSBUUlVFLCAKICAgIC5uYW1lcyA9ICJ7Y29sfV97Zm59IgogICAgKSkKZGVtb19zdW0gCgpkZW1vX3N1bSA8LSBhcy5saXN0KGRlbW9fc3VtKQpgYGAKCiMjIyBBZ3RhIEJhbmQgU2l6ZQoKRGF0YSByZWdhcmRpbmcgY2FtcCBzaXplIG9mIEFndGEgaHVudGVyLWdhdGhlcmVycyB3YXMgb2J0YWluZWQgZnJvbSBhIHN0dWR5IG9mIDYxNSBpbmRpdmlkdWFscyBmcm9tIDE1IGNhbXBzIGluIGluIHRoZSBtdW5pY2lwYWxpdHkgb2YgUGFsYW5hbiwgdGhlIE5vcnRoZXJuIFBoaWxpcHBpbmVzIHB1Ymxpc2hlZCBieSBEeWJsZSBldCBhbC4gKDIwMjEpLgoKYGBge3J9CiMgSW1wb3J0IENhbXAgZGF0YSBmcm9tIE1hcmsgRHlibGUKY2FtcHMuZGF0YSA8LSByZWFkX2NzdigiQWd0YV9EYXRhL2NhbXBzLmNzdiIpCgpoZWFkKGNhbXBzLmRhdGEpCmBgYAoKCmBgYHtyfQojIEV4cGxvcmUgY2FtcCBzaXplCmhpc3QoY2FtcHMuZGF0YSRjYW1wX3RvdGFsKQoKY2FtcC5zaXplIDwtIGNhbXBzLmRhdGEgJT4lCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKGNhbXBfdG90YWwpLAogICAgICAgICAgICBzZCA9IHNkKGNhbXBfdG90YWwpLAogICAgICAgICAgICBtaW4gPSBtaW4oY2FtcF90b3RhbCksCiAgICAgICAgICAgIG1heCA9IG1heChjYW1wX3RvdGFsKSwKICAgICAgICAgICAgdmFyID0gdmFyKGNhbXBfdG90YWwpKQpjYW1wLnNpemUKYGBgCgojIyMgUGF0aG9nZW4gWAoKRm9yIHRoZSBwdXJwb3NlIG9mIHRoaXMgaW52ZXN0aWdhdGlvbiB3ZSBmb3JtdWxhdGVkIGEgaHlwb3RoZXRpY2FsIHJlc3BpcmF0b3J5IHBhdGhvZ2VuLCByZWZlcnJlZCB0byBhcyBwYXRob2dlbiBYLiBUYWtpbmcgaW50byBhY2NvdW50IHRoZSBiaW9sb2dpY2FsIHRyYWRlLW9mZnMgYmV0d2VlbiBoaWdoIHRyYW5zbWlzc2liaWxpdHkgYW5kIGhpZ2ggcGF0aG9nZW5pY2l0eSwgcGF0aG9nZW4gWCB3YXMgZGVjaWRlZCB0byBiZSBoaWdobHkgaW5mZWN0aW91cyB3aXRoIGEgcmVsYXRpdmVseSBsb3cgY2FzZSBmYXRhbGl0eSByYXRlIG9mIDAuMDA1LiBUcmFuc21pc3Npb24gb2NjdXJyZWQgdmlhIGNsb3NlIGNvbnRhY3Qgd2l0aCBhbiBpbmZlY3RlZCBpbmRpdmlkdWFsLiBJbmZlY3Rpb24gd2FzIGNoYXJhY3RlcmlzZWQgYnkgYSBsYXRlbnQgcGVyaW9kIG9mIDUuNyBkYXlzIGZvbGxvd2VkIGJ5IGFuIGluZmVjdGlvdXMgcGVyaW9kIG9mIDUgZGF5cy4gSW5kaXZpZHVhbHMgd2hvIHJlY292ZXJlZCBmcm9tIGluZmVjdGlvbiB3ZXJlIGltbXVuZSBmb3IgMTAwIGRheXMsIGFmdGVyIHdoaWNoIGltbXVuaXR5IHdhbmVkIGFuZCBpbmRpdmlkdWFscyBiZWNhbWUgc3VzY2VwdGlibGUgdG8gcmUtaW5mZWN0aW9uLiBCYXNlZCBvbiB0aGVzZSBjaGFyYWN0ZXJpc3RpY3MsIHRoZSBwYXJhbWV0ZXJzIGluIHRhYmxlIDEgd2VyZSBhc3N1bWVkIGFuZCBpbnB1dCBpbnRvIHRoZSBmaW5hbCBtb2RlbHMuCgoqKlBhcmFtZXRlcioqIHwgKipSYXRlKiogfCAqKlZhbHVlKioKLS0tIHwgLS0tIHwgLS0tICAKJFxiZXRhJCAgICAgICB8ICBUcmFuc21pc3Npb24gfCAwLjYgCiRcc2lnbWEkICAgICAgfCAgSW5mZWN0aW91cyAgIHwgMC4xNzUgCiRcZ2FtbWEkICAgICAgfCAgUmVjb3ZlcnkgICAgIHwgMC4yIAokXGFscGhhJCAgICAgIHwgIERlYXRoIGZyb20gSW5mZWN0aW9uIHwgMC4wMDEKJFxvbWVnYSQgICAgICB8ICBXYW5pbmcgSW1tdW5pdHkgfCAwLjAxCgoKCiMjIFNpbmdsZSBQb3B1bGF0aW9uIE1vZGVsCgpUbyBpbnZlc3RpZ2F0ZSB0aGUgcGVyc2lzdGVuY2Ugb2YgYSBoeXBvdGhldGljYWwgcmVzcGlyYXRvcnkgcGF0aG9nZW4gaW4gaHVudGVyLWdhdGhlcmVycywgdGhpcyBzdHVkeSBjaG9zZSB0byBzaW11bGF0ZSBkaXNlYXNlIHRyYW5zbWlzc2lvbiB1c2luZyBhIGNvbXBhcnRtZW50IG1vZGVsIGFwcHJvYWNoIGFzIG91dGxpbmVkIGluIHRoZSBpbnRyb2R1Y3Rpb24uIFR3byBtb2RlbHMgd2VyZSBjb25zdHJ1Y3RlZCB0byBpbnZlc3RpZ2F0ZSBjb21wYXJlIHRoZSBlZmZlY3Qgb2YgbWV0YXBvcHVsYXRpb24gc3RydWN0dXJlIG9uIGRpc2Vhc2UgcGVyc2lzdGVuY2UuIFRoaXMgZmlyc3QgZGVzY3JpYmVzIHRoZSB0cmFuc21pc3Npb24gb2YgYSBwYXRob2dlbiB3aXRoaW4gYSBzaW5nbGUgcG9wdWxhdGlvbiB3aXRoIGRlbW9ncmFwaHkgYW5kIHdhbmluZyBpbW11bml0eSB0byByZS1pbmZlY3Rpb24gb3ZlciB0aW1lLgoKClwKPGNlbnRlcj4KCgohWypGaWd1cmUgMSAtIEZsb3cgZGlhZ3JhbSBvZiBTRUlSUyBtb2RlbCBvZiB0cmFuc21pc3Npb24qXShQbG90cy9TRUlSU19GbG93X0RpYWdyYW0ucG5nKQoKCjwvY2VudGVyPgpcClwKXAoKXGJlZ2lue2FsaWduKn0KICBcZnJhY3t7e1xtYXRocm17ZH19U319e3t7XG1hdGhybXtkfX10fX0gJiA9IFx1bmRlcmJyYWNlIHtcbXUgTn1fe3tcbWF0aHJte2JpcnRofX19fiAtIH5cdW5kZXJicmFjZSB7XGZyYWN7XGJldGEgU0l9e059fV97e1xtYXRocm17aW5mZWN0aW9ufX19fn4gKyBcdW5kZXJicmFjZSB7XG9tZWdhIFJ9X3t7XG1hdGhybXtsb3N0fX1cLHtcbWF0aHJte2ltbXVuaXR5fX19IC0gXHVuZGVyYnJhY2Uge1xtdSBTfV97e1xtYXRocm17ZGVhdGh9fX0gXFwKICBcZnJhY3t7e1xtYXRocm17ZH19RX19e3t7XG1hdGhybXtkfX10fX0gJiA9IFx1bmRlcmJyYWNlIHtcZnJhY3tcYmV0YSBTSX17Tn19X3t7XG1hdGhybXtpbmZlY3Rpb259fX1+IC0gflx1bmRlcmJyYWNlIHtcc2lnbWEgRX1fe3tcbWF0aHJte2xhdGVuY3l9fX0gLSBcdW5kZXJicmFjZSB7XG11IEV9X3t7XG1hdGhybXtkZWF0aH19fSBcXAogIFxmcmFje3t7XG1hdGhybXtkfX1JfX17e3tcbWF0aHJte2R9fXR9fSAmID0gXHVuZGVyYnJhY2Uge1xzaWdtYSBFfV97e1xtYXRocm17bGF0ZW5jeX19fSAtIFx1bmRlcmJyYWNlIHtcZ2FtbWEgSX1fe3tcbWF0aHJte3JlY292ZXJ5fX19IC0gflx1bmRlcmJyYWNlIHtcbGVmdCgge1xtdSArIFxhbHBoYSB9IFxyaWdodClJfV97e1xtYXRocm17ZGVhdGh9fX0gXFwKICBcZnJhY3t7e1xtYXRocm17ZH19Un19e3t7XG1hdGhybXtkfX10fX0gJiA9IFx1bmRlcmJyYWNlIHtcZ2FtbWEgSX1fe3tcbWF0aHJte3JlY292ZXJ5fX19IC0gXHVuZGVyYnJhY2Uge1xvbWVnYSBSfV97e1xtYXRocm17bG9zdH19XCB7XG1hdGhybXtpbW11bml0eX19fSAtIFx1bmRlcmJyYWNlIHtcbXUgUn1fe3tcbWF0aHJte2RlYXRofX19ClxlbmR7YWxpZ24qfQoKXApcCgoKV2hlcmUgdHJhbnNtaXNzaW9uIGlzIGZyZXF1ZW5jeSBkZXBlbmRlbnQsICR7XGZyYWN7XGJldGEgU0l9e059fSQsICRcZnJhY3sxfXtcc2lnbWF9JCBpcyB0aGUgZHVyYXRpb24gb2YgdGhlIGxhdGVudCBwaGFzZSwgJFxmcmFjezF9e1xnYW1tYX0kIGlzIHRoZSBkdXJhdGlvbiBvZiBpbmZlY3Rpb24sICRcZnJhY3sxfXtcb21lZ2F9JCBpcyB0aGUgZHVyYXRpb24gb2YgaW1tdW5pdHkgYW5kIGRlYXRoIGZyb20gaW5mZWN0aW9uIG9jY3VycyBhdCB0aGUgcmF0ZSAkXGFscGhhJC4gSW5kaXZpZHVhbHMgY2FuIGJlIGJvcm4gaW50byBTIGFuZCBkaWUgbmF0dXJhbGx5IGZyb20gYW55IGNvbXBhcnRtZW50IGF0IGEgcmF0ZSBvZiAkXG11JC4KCgoKIyMjIE1vZGVsIFNldC11cAoKTW9kZWwgd2FzIHNldCB1cCB3aXRoIGEgc2luZ2xlIHJhbmRvbWx5IHNlbGVjdGVkIGNhbXAgc2l6ZSB3aXRoIGEgc2luZ2xlIGluZmVjdGVkIGluZGl2aWR1YWwgYW5kIHBhcmFtZXRlcnMgZm9yIHBhdGhvZ2VuIFguIAoKYGBge3J9CiMgRGVmaW5lIFBhcmFtZW50ZXJzCk4gPC0gICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBQb3B1bGF0aW9uIHNpemUKaW5pdGlhbF9pbmZlY3RlZCA8LSAgMSAgICAjIEluaXRpYWwgaW5mZWN0ZWQKc2ltTmFtZSA8LSAiU0VJUlMgbW9kZWwiICAgICAgICMgU2ltdWxhdGlvbiBuYW1lCnRmIDwtIDM2NSozCgojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zIDwtIGxpc3QoCiAgYmV0YSA9IDAuNiwKICBzaWdtYSA9IDAuMTc1LCAgICAgICAgICAgICAgICAgICAgICAgICAgIyBFIHRvIEkgcmF0ZQogIGdhbW1hID0gMC4yLCAgICAgICAgICAgICAgICAgICAgICAgICAgICMgSSB0byBSIHJhdGUKICBvbWVnYSA9IDEvMTAwLCAgICAgICAgICAgICAgICAgICAgICAgICAjIFIgdG8gUyByYXRlCiAgbXUgPSBkZW1vX3N1bSRCaXJ0aF9yYXRlX2RhaWx5X01lYW4sICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGgvZGVhdGggcmF0ZSBwZXIgcGVyc29uIHBlciBkYXkKICBhbHBoYSA9IDEvMTAwMCkgCgojQ3JlYXRlIHRoZSBuYW1lZCBpbml0aWFsIHN0YXRlIHZlY3RvciBmb3IgdGhlIFUtcGF0Y2ggc3lzdGVtLgoKeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCm5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgojIERlZmluZSB0aGUgc3RhdGUgY2hhbmdlIG1hdHJpeCBmb3IgYSBzaW5nbGUgcGF0Y2gKbnUgPC0gbWF0cml4KGMoIC0xLCAgMCwgIDAsICsxLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAjIFMKICAgICAgICAgICAgICAgICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIDAsICAwLCAjIEUKICAgICAgICAgICAgICAgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgLTEsICMgSQogICAgICAgICAgICAgICAgMCwgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIyBSIAogICAgICAgICAgICAgICAgMCwgIDAsICAwLCAgMCwgKzEsIC0xICwtMSwgLTEsIC0xLCAtMSksICMgTgogICAgICAgICAgICAgbnJvdz01LGJ5cm93PVRSVUUpCgojIERlZmluZSBwcm9wZW5zaXR5IGZ1bmN0aW9ucwphIDwtYygKICAgICAgICBwYXN0ZTAoIihiZXRhKkkvTikqUyIpLCAjIEluZmVjdGlvbgogICAgICAgIHBhc3RlMCgic2lnbWEqRSIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmVjb21lcyBpbmZlY2lvdXMKICAgICAgICBwYXN0ZTAoImdhbW1hKkkiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFJlY292ZXJ5IGZyb20gaW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJvbWVnYSpSIiksICAgICAgICMgTG9zcyBvZiBpbW11bml0eQogICAgICAgIHBhc3RlMCgibXUqTiIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aHMKICAgICAgICBwYXN0ZTAoIm11KlMiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUykKICAgICAgICBwYXN0ZTAoIm11KkUiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoRSkKICAgICAgICBwYXN0ZTAoIm11KkkiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoSSkKICAgICAgICBwYXN0ZTAoIm11KlIiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUikKICAgICAgICBwYXN0ZTAoImFscGhhKkkiKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyBmcm9tIGluZmVjdGlvbgogICAgICAgIAogICAgICApCgpgYGAKCkRlZmluZSBmdW5jdGlvbnMgdG8gY2FsY3VsYXRlIFIwIGFuZCBleHBlY3RlZCBudW1iZXIgb2Ygc3VzY2VwdGlibGVzIGF0IGVxdWlsaWJyaXVtLCBhbmQgY3JpdGljYWwgY29tbXVuaXR5IHNpemUgKERpZWttYW5uIGV0IGFsLiwgMjAxMikuCgpgYGB7cn0KIFIwIDwtIGZ1bmN0aW9uKHBhcm1zKSB7CiAgIChwYXJtcyRzaWdtYS8ocGFybXMkc2lnbWEgKyBwYXJtcyRtdSkpICogKHBhcm1zJGJldGEvcGFybXMkZ2FtbWEgKyBwYXJtcyRtdSArIHBhcm1zJGFscGhhKQogfSAKICAKRUlFIDwtIGZ1bmN0aW9uKFIwLCBwYXJtcykgewogIHkgPSAoKFIwIC0gMSkgKiBwYXJtcyRvbWVnYSkgLyAocGFybXMkZ2FtbWEgKiBSMCkKICByZXR1cm4oeSkKfQoKQ0NTIDwtIGZ1bmN0aW9uKGVwc2lsb24sIFIwKSB7CiAgeSA9IDEvKChlcHNpbG9uXjIpKigoMS0oMS9SMCkpXjIpKQogIHJldHVybih5KQp9CmBgYAoKIyMjIFJ1biBTaW5nbGUgUG9wdWxhdGlvbiBNb2RlbApgYGB7cn0KCiMgQ2FsY3VsYXRlIFIwLCBleHBlY3RlZCBudW1iZXIgb2YgaW5mZWN0ZWRzIGF0IGVxdWlsaWJyaXVtLCBtYWduaXR1ZGUgb2Ygb3NjaWxsYXRpb24gYW5kIENDUwpSMF9zaW5nbGUgPC0gUjAocGFybXMpClIwX3NpbmdsZQoKRUlFX3NpbmdsZSA8LSBFSUUoUjBfc2luZ2xlLCBwYXJtcykgIyBwcm9wb3J0aW9uIG9mIGV4cGVjdGVkIGluZmVjdGVkcyBhdCBlcXVpbGlicml1bQpFSUVfc2luZ2xlCgpleHBleHRlZF9pbmZlY3RlZHMgPC0gRUlFX3NpbmdsZSpOICMgbnVtYmVyIG9mIGV4cGVjdGVkIGluZmVjdGVkcyBhdCBlcXVpbGlicml1bQpleHBleHRlZF9pbmZlY3RlZHMKCnNxcnQoTikgIyBtYWduaXR1ZGUgb2Ygb3NjaWxsYXRpb25zIAoKZXBzaWxvbiA8LSAoNS43LzM2NSkvMjMgIyBkdXJhdGlvbiBvZiBpbmZlY3Rpb24gaW4geWVhcnMgZGl2aWRlZCBieSBhdmcgbGlmZSBleHBlY3RhbmN5IApDQ1Nfc2luZ2xlIDwtIENDUyhlcHNpbG9uLCBSMF9zaW5nbGUpICMgQXZlcmFnZSBsaWZlIGV4cGVjdGFuY3kgYXMgcGVyIEthcGxhbiAoY3J1ZGUpCkNDU19zaW5nbGUKYGBgCgpgYGB7cn0KIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCgyMSkKb3V0IDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtcywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKSAKCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhIDwtIG91dCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKc2luZ2xlX3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGEsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZShhbHBoYT0wLjgpKwogIGxhYnMoeD0iVGltZSAoRGF5cykiLAogICAgICAgeT0iTnVtYmVyIG9mIEluZGl2aWR1YWxzIiwgCiAgICAgICBjb2xvdXI9IlN0YXRlIikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZXhwZXh0ZWRfaW5mZWN0ZWRzLCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArCiAgdGhlbWVfYncoKQoKc2luZ2xlX3Bsb3QKCmdnc2F2ZShmaWxlbmFtZSA9ICJzaW5nbGVfcGxvdC5wZGYiLCAKICAgICAgIHBsb3QgPSBzaW5nbGVfcGxvdCwKICAgICAgIGRldmljZSA9ICJwZGYiLAogICAgICAgd2lkdGggPSA3LCAKICAgICAgIGhlaWdodCA9IDMsCiAgICAgICBwYXRoID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvUGxvdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscyIpCmBgYAoKYGBge3J9CnBsb3RfZGF0YSAlPiUKICBmaWx0ZXIoc3RhdGUgPT0gIkkiKSAlPiUKICBzbGljZV9tYXgoY291bnQpCmBgYApPdXRicmVhayBwZWFrZWQgYXQgZGF5IDI1IHdpdGggMTQgaW5mZWN0ZWQgaW5kaXZpZHVhbHMuCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3QgPC0gbGlzdCgpCnNpbV9saXN0IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBzZXQuc2VlZChpKQogIG91dF8xMDAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YSA8LSBvdXRfMTAwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdFtbaV1dIDwtIHNpbV9kYXRhCn0KCnNpbV9vdXRwdXQgPC0gYmluZF9yb3dzKHNpbV9saXN0KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0IDwtIHNpbV9vdXRwdXQgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpoZWFkKHNpbV9vdXRwdXQpCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnkgPC0gc2ltX291dHB1dCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwMCkKc2ltX3N1bW1hcnkKYGBgCgojIyMgVmFyeWluZyB3YWluaW5nIGltbXVuaXR5IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQpXYW5pbmcgaW1tdW5pdHkgd2FzIHRob3VnaHQgdG8gcGxheSBhbiBpbXBvcnRhbnQgcm9sZSBpbiB0aGUgcGVyc2lzdGVuY2Ugb2YgcGF0aG9nZW4gWCBzbyB3ZSBpbmNyZW1lbnRhbGx5IGluY3JlYXNlZCB0aGUgZHVyYXRpb24gb2YgaW1tdW5pdHkgKGJ5IGRlY3JlYXNpbmcgJFxvbWVnYSQpIGFuZCBjYWxjdWxhdGVkIHRoZSBwcm9iYWJpbGl0eSBvZiBwZXJzaXN0ZW5jZSBhZnRlciAzIHllYXJzIGluIDEwMDAgc3RvY2hhc3RpYyBzaW11bGF0aW9ucy4gRHVyYXRpb24gb2YgaW1tdW5pdHkgd2FzIGluY3JlYXNlZCBmcm9tIDEgZGF5IHRvIGEgeWVhci4KCiMjIyMgMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzAgPC0gcGFybXMKcGFybXNfMCRvbWVnYSA8LSAwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8wIDwtIG91dF8wJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8wCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMCA8LSBsaXN0KCkKc2ltX2xpc3RfMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzAgPC0gb3V0XzEwMF8wJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8wW1tpXV0gPC0gc2ltX2RhdGFfMAp9CgpzaW1fb3V0cHV0XzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMCA8LSBzaW1fb3V0cHV0XzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8wIDwtIHNpbV9vdXRwdXRfMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAwKQpzaW1fc3VtbWFyeV8wCmBgYAoKCgoKIyMjIyAxIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMSA8LSBwYXJtcwpwYXJtc18xJG9tZWdhIDwtIDEKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc18xLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzEgPC0gb3V0XzEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzEKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xIDwtIGxpc3QoKQpzaW1fbGlzdF8xIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMSA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMSA8LSBvdXRfMTAwXzEkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzFbW2ldXSA8LSBzaW1fZGF0YV8xCn0KCnNpbV9vdXRwdXRfMSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xIDwtIHNpbV9vdXRwdXRfMSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzEgPC0gc2ltX291dHB1dF8xICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEpCnNpbV9zdW1tYXJ5XzEKYGBgCgoKCgoKIyMjIyAzIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMyA8LSBwYXJtcwpwYXJtc18zJG9tZWdhIDwtIDEvMwoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzMgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzMsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMyA8LSBvdXRfMyRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzMsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMwpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzMgPC0gbGlzdCgpCnNpbV9saXN0XzMgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8zIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zIDwtIG91dF8xMDBfMyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM1tbaV1dIDwtIHNpbV9kYXRhXzMKfQoKc2ltX291dHB1dF8zIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzMgPC0gc2ltX291dHB1dF8zICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMyA8LSBzaW1fb3V0cHV0XzMgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zKQpzaW1fc3VtbWFyeV8zCmBgYAoKIyMjIyA3IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNyA8LSBwYXJtcwpwYXJtc183JG9tZWdhIDwtIDEvNwoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzcgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzcsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfNyA8LSBvdXRfNyRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF83IDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzcsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfNwpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzcgPC0gbGlzdCgpCnNpbV9saXN0XzcgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF83IDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzcsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV83IDwtIG91dF8xMDBfNyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfN1tbaV1dIDwtIHNpbV9kYXRhXzcKfQoKc2ltX291dHB1dF83IDwtIGJpbmRfcm93cyhzaW1fbGlzdF83KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzcgPC0gc2ltX291dHB1dF83ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF83CgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNyA8LSBzaW1fb3V0cHV0XzcgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83KQpzaW1fc3VtbWFyeV83CmBgYAoKIyMjIyAxMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzEwIDwtIHBhcm1zCnBhcm1zXzEwJG9tZWdhIDwtIDEvMTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xMCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTAgPC0gb3V0XzEwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzEwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzEwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzEwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTAgPC0gbGlzdCgpCnNpbV9saXN0XzEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xMCA8LSBvdXRfMTAwXzEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xMFtbaV1dIDwtIHNpbV9kYXRhXzEwCn0KCnNpbV9vdXRwdXRfMTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzEwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzEwIDwtIHNpbV9vdXRwdXRfMTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzEwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTAgPC0gc2ltX291dHB1dF8xMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwKQpzaW1fc3VtbWFyeV8xMApgYGAKCiMjIyMgMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18yMCA8LSBwYXJtcwpwYXJtc18yMCRvbWVnYSA8LSAxLzIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMjAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzIwIDwtIG91dF8yMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8yMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8yMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8yMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzIwIDwtIGxpc3QoKQpzaW1fbGlzdF8yMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzIwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMjAgPC0gb3V0XzEwMF8yMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMjBbW2ldXSA8LSBzaW1fZGF0YV8yMAp9CgpzaW1fb3V0cHV0XzIwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8yMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8yMCA8LSBzaW1fb3V0cHV0XzIwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8yMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzIwIDwtIHNpbV9vdXRwdXRfMjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yMCkKc2ltX3N1bW1hcnlfMjAKYGBgCgojIyMjIDMwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMzAgPC0gcGFybXMKcGFybXNfMzAkb21lZ2EgPC0gMS8zMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzMwIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc18zMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zMCA8LSBvdXRfMzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zMCA8LSBsaXN0KCkKc2ltX2xpc3RfMzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8zMCA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18zMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzMwIDwtIG91dF8xMDBfMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzMwW1tpXV0gPC0gc2ltX2RhdGFfMzAKfQoKc2ltX291dHB1dF8zMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMzAgPC0gc2ltX291dHB1dF8zMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zMCA8LSBzaW1fb3V0cHV0XzMwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzApCnNpbV9zdW1tYXJ5XzMwCmBgYAoKIyMjIyA0MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzQwIDwtIHBhcm1zCnBhcm1zXzQwJG9tZWdhIDwtIDEvNDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF80MCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfNDAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfNDAgPC0gb3V0XzQwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzQwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzQwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzQwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNDAgPC0gbGlzdCgpCnNpbV9saXN0XzQwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNDAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNDAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV80MCA8LSBvdXRfMTAwXzQwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF80MFtbaV1dIDwtIHNpbV9kYXRhXzQwCn0KCnNpbV9vdXRwdXRfNDAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzQwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzQwIDwtIHNpbV9vdXRwdXRfNDAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzQwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNDAgPC0gc2ltX291dHB1dF80MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzQwKQpzaW1fc3VtbWFyeV80MApgYGAKCiMjIyMgNTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc181MCA8LSBwYXJtcwpwYXJtc181MCRvbWVnYSA8LSAxLzUwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfNTAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzUwIDwtIG91dF81MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF81MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV81MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF81MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzUwIDwtIGxpc3QoKQpzaW1fbGlzdF81MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzUwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNTAgPC0gb3V0XzEwMF81MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNTBbW2ldXSA8LSBzaW1fZGF0YV81MAp9CgpzaW1fb3V0cHV0XzUwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF81MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF81MCA8LSBzaW1fb3V0cHV0XzUwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF81MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzUwIDwtIHNpbV9vdXRwdXRfNTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS81MCkKc2ltX3N1bW1hcnlfNTAKYGBgCgojIyMjIDYwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNjAgPC0gcGFybXMKcGFybXNfNjAkb21lZ2EgPC0gMS82MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzYwIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc182MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV82MCA8LSBvdXRfNjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfNjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfNjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfNjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF82MCA8LSBsaXN0KCkKc2ltX2xpc3RfNjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF82MCA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc182MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzYwIDwtIG91dF8xMDBfNjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzYwW1tpXV0gPC0gc2ltX2RhdGFfNjAKfQoKc2ltX291dHB1dF82MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfNjAgPC0gc2ltX291dHB1dF82MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV82MCA8LSBzaW1fb3V0cHV0XzYwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNjApCnNpbV9zdW1tYXJ5XzYwCmBgYAoKIyMjIyA3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzcwIDwtIHBhcm1zCnBhcm1zXzcwJG9tZWdhIDwtIDEvNzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF83MCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfNzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfNzAgPC0gb3V0XzcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzcwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzcwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNzAgPC0gbGlzdCgpCnNpbV9saXN0XzcwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNzAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV83MCA8LSBvdXRfMTAwXzcwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF83MFtbaV1dIDwtIHNpbV9kYXRhXzcwCn0KCnNpbV9vdXRwdXRfNzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzcwIDwtIHNpbV9vdXRwdXRfNzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNzAgPC0gc2ltX291dHB1dF83MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcwKQpzaW1fc3VtbWFyeV83MApgYGAKCiMjIyMgODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc184MCA8LSBwYXJtcwpwYXJtc184MCRvbWVnYSA8LSAxLzgwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfODAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzgwIDwtIG91dF84MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF84MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV84MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF84MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzgwIDwtIGxpc3QoKQpzaW1fbGlzdF84MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzgwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfODAgPC0gb3V0XzEwMF84MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfODBbW2ldXSA8LSBzaW1fZGF0YV84MAp9CgpzaW1fb3V0cHV0XzgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF84MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF84MCA8LSBzaW1fb3V0cHV0XzgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF84MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzgwIDwtIHNpbV9vdXRwdXRfODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS84MCkKc2ltX3N1bW1hcnlfODAKYGBgCgojIyMjIDE1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE1MCA8LSBwYXJtcwpwYXJtc18xNTAkb21lZ2EgPC0gMS8xNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNTAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzE1MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNTAgPC0gb3V0XzE1MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE1MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE1MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTUwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzE1MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE1MCA8LSBvdXRfMTAwXzE1MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTUwW1tpXV0gPC0gc2ltX2RhdGFfMTUwCn0KCnNpbV9vdXRwdXRfMTUwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTUwIDwtIHNpbV9vdXRwdXRfMTUwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNTAgPC0gc2ltX291dHB1dF8xNTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xNTApCnNpbV9zdW1tYXJ5XzE1MApgYGAKCiMjIyMgMTgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTgwIDwtIHBhcm1zCnBhcm1zXzE4MCRvbWVnYSA8LSAxLzE4MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzEwMCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMTgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE4MCA8LSBvdXRfMTgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE4MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xODAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTgwIDwtIGxpc3QoKQpzaW1fbGlzdF8xODAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xODAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTgwIDwtIG91dF8xMDBfMTgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xODBbW2ldXSA8LSBzaW1fZGF0YV8xODAKfQoKc2ltX291dHB1dF8xODAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE4MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xODAgPC0gc2ltX291dHB1dF8xODAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE4MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE4MCA8LSBzaW1fb3V0cHV0XzE4MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE4MCkKc2ltX3N1bW1hcnlfMTgwCmBgYAoKCiMjIyMgMzY1IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMzY1IDwtIHBhcm1zCnBhcm1zXzM2NSRvbWVnYSA8LSAxLzM2NQoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzM2NSA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMzY1LAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzM2NSA8LSBvdXRfMzY1JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzM2NSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zNjUsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMzY1CmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMzY1IDwtIGxpc3QoKQpzaW1fbGlzdF8zNjUgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8zNjUgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMzY1LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMzY1IDwtIG91dF8xMDBfMzY1JGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zNjVbW2ldXSA8LSBzaW1fZGF0YV8zNjUKfQoKc2ltX291dHB1dF8zNjUgPC0gYmluZF9yb3dzKHNpbV9saXN0XzM2NSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zNjUgPC0gc2ltX291dHB1dF8zNjUgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzM2NQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzM2NSA8LSBzaW1fb3V0cHV0XzM2NSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzM2NSkKc2ltX3N1bW1hcnlfMzY1CmBgYAoKCgojIyMjIFJlc3VsdHMKYGBge3J9CndhbmluZ19yZXN1bHRzX3NpbmdsZSA8LSBzaW1fc3VtbWFyeSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMSkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzMpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV83KSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8yMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzMwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNDApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV81MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzYwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV84MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzEwMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE1MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzM2NSkgJT4lCiAgbXV0YXRlKGltbXVuaXR5X2R1cmF0aW9uID0gMS9vbWVnYSkgJT4lCiAgYXJyYW5nZShpbW11bml0eV9kdXJhdGlvbikgJT4lCiAgbXV0YXRlKG1vZGVsPSJzaW5nbGUiLAogICAgICAgICBwYXRjaGVzID0gMSkKCndyaXRlX2Nzdih3YW5pbmdfcmVzdWx0c19zaW5nbGUsIGZpbGUgPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzL1Jlc3VsdHMvd2FuaW5nX3Jlc3VsdHNfc2luZ2xlLmNzdiIpCgp3YW5pbmdfcmVzdWx0c19zaW5nbGUKCmBgYAoKYGBge3J9CmdncGxvdCh3YW5pbmdfcmVzdWx0c19zaW5nbGUsIGFlcyhpbW11bml0eV9kdXJhdGlvbiwgc3VtX3BlcnNpc3QpKSArCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX2J3KCkKYGBgCgoKCgojIyA3LVBhdGNoIE1ldGFwb3B1bGF0aW9uIE1vZGVsIAoKUmVjZW50IHN0dWRpZXMgaGF2ZSBzdWdnZXN0ZWQgdGhhdCBwcmUtYWdyaWN1bHR1cmFsIGh1bnRlci1nYXRoZXJlcnMgZGlkIG5vdCBsaXZlIGluIHNtYWxsIGlzb2xhdGVkIGdyb3VwcyBidXQgZnJvbWVkIGludGVyY29ubmVjdGVkIG11bHRpLWNhbXAgbmV0d29ya3MuIFRvIGludmVzdGlnYXRlIHRoaXMgd2UgYnVpbHQgYSBzZWNvbmQgcG9wdWxhdGlvbiB0aGF0IGFjY291bnRzIGZvciBtZXRhcG9wdWxhdGlvbiBzdHJ1Y3R1cmUgb2YgaHVudGVyLWdhdGhlcmVycy4gVGhlIHNlY29uZCBtb2RlbCBmb2xsb3dzIGFuIGFsbW9zdCBpZGVudGljYWwgZm9ybWF0IGFzIHRoZSBzaW5nbGUgcG9wdWxhdGlvbiBtb2RlbCwgYnV0IGluc3RlYWQgaGFzIGJlZW4gZXhwYW5kZWQgdG8gYWNjb21tb2RhdGUgdGhlIG1ldGFwb3B1bGF0aW9uIHN0cnVjdHVyZSBvZiBtdWx0aS1iYW5kIGh1bnRlci1nYXRoZXJlciBncm91cHM6CgoKXGJlZ2lue2FsaWduKn0KXGZyYWN7e3tcbWF0aHJte2R9fVN9fXt7e1xtYXRocm17ZH19dH19ICYgPSBcdW5kZXJicmFjZSB7XG11X2kgTl9pfV97e1xtYXRocm17YmlydGh9fX1+IC0gflx1bmRlcmJyYWNlIHtcYmlnZ2woXGZyYWN7XGJldGFfe2lpfSBJX2l9e05faX0gKyBcZnJhY3tcYmV0YV97aml9IElfan0ge05fan0gKyAuLi4gXGJpZ2dyKVNfaX1fe3tcbWF0aHJte2luZmVjdGlvbn19fX5+ICsgXHVuZGVyYnJhY2Uge1xvbWVnYV9pIFJfaX1fe3tcbWF0aHJte2xvc3R9fVwse1xtYXRocm17aW1tdW5pdHl9fX0gLSBcdW5kZXJicmFjZSB7XG11X2kgU19pfV97e1xtYXRocm17ZGVhdGh9fX0gXFwKXGZyYWN7e3tcbWF0aHJte2R9fUV9fXt7e1xtYXRocm17ZH19dH19ICYgPSBcdW5kZXJicmFjZSB7XGJpZ2dsKFxmcmFje1xiZXRhX3tpaX0gSV9pfXtOX2l9ICsgXGZyYWN7XGJldGFfe2ppfSBJX2p9IHtOX2p9ICsgLi4uIFxiaWdncilTX2l9X3t7XG1hdGhybXtpbmZlY3Rpb259fX1+IC0gflx1bmRlcmJyYWNlIHtcc2lnbWFfaSBFX2l9X3t7XG1hdGhybXtsYXRlbmN5fX19IC0gXHVuZGVyYnJhY2Uge1xtdV9pIEVfaX1fe3tcbWF0aHJte2RlYXRofX19IFxcClxmcmFje3t7XG1hdGhybXtkfX1JfX17e3tcbWF0aHJte2R9fXR9fSAmID0gXHVuZGVyYnJhY2Uge1xzaWdtYV9pIEVfaX1fe3tcbWF0aHJte2xhdGVuY3l9fX0gLSBcdW5kZXJicmFjZSB7XGdhbW1hX2kgSV9pfV97e1xtYXRocm17cmVjb3Zlcnl9fX0gLSB+XHVuZGVyYnJhY2Uge1xsZWZ0KCB7XG11X2kgKyBcYWxwaGFfaSB9IFxyaWdodClJX2l9X3t7XG1hdGhybXtkZWF0aH19fSBcXApcZnJhY3t7e1xtYXRocm17ZH19Un19e3t7XG1hdGhybXtkfX10fX0gJiA9IFx1bmRlcmJyYWNlIHtcZ2FtbWFfaSBJX2l9X3t7XG1hdGhybXtyZWNvdmVyeX19fSAtIFx1bmRlcmJyYWNlIHtcb21lZ2FfaSBSX2l9X3t7XG1hdGhybXtsb3N0fX1cIHtcbWF0aHJte2ltbXVuaXR5fX19IC0gXHVuZGVyYnJhY2Uge1xtdV9pIFJfaX1fe3tcbWF0aHJte2RlYXRofX19ClxlbmR7YWxpZ24qfQoKVGhlc2UgY291cGxlZCBkaWZmZXJlbnRpYWwgZXF1YXRpb25zIGRlc2NyaWJlIHRoZSB3aXRoaW4tcGF0Y2ggU0VJUlMtdHlwZSBkeW5hbWljcyBvZiB0aGUgJGkkdGggcGF0Y2ggd2hlcmUgdGhlIGZvcmNlIG9mIGluZmVjdGlvbiBpcyBkcml2ZW4gYnkgY29udGFjdCBvZiBzdXNjZXB0aWJsZXMgd2l0aCBpbmZlY3RlZHMgd2l0aGluIHRoZSAkaSR0aCBwYXRjaCBhbmQgaW4gdGhlICRqJHRoIG90aGVyIHBhdGNoZXMuIEJvdGggbW9kZWxzIGFzc3VtZSB0aGF0IGNvbXBhcnRtZW50cyBhcmUgd2VsbC1taXhlZCBhbmQgdGhhdCB0aGUgd2FpdGluZyB0aW1lcyBiZXR3ZWVuIGNvbXBhcnRtZW50cyBhcmUgZXhwb25lbnRpYWxseSBkaXN0cmlidXRlZC4gCgoKCgojIyMgTW9kZWwgU2V0LXVwCldlIGZpcnN0IG1vZGVsZWQgdHJhbnNtaXNzaW9uIGluIGEgbWV0YXBvcHVsYXRpb24gb2YgNyBjYW1wcywgYXMgb2JzZXJ2ZWQgYnkgTWlnbGlhbm8gZXQgYWwuICgyMDIzKSwgd2l0aCBvbmUgaW5pdGlhbGx5IGluZmVjdGVkIGluZGl2aWR1YWwgZnJvbSBhIHJhbmRvbWx5IHNlbGVjdGVkIHBhdGNoLiAKCmBgYHtyfQojIERlZmluZSBQYXJhbWVudGVycwpwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFBhdGNoIHNpemUKVSA8LSBsZW5ndGgocGF0Y2hQb3BTaXplKSAgICAgICAgICAgICAgICAgICAgIyBOdW1iZXIgb2YgcGF0Y2hlcwppbml0aWFsX2luZmVjdGVkIDwtICBhcy52ZWN0b3Iocm11bHRpbm9tKDEsIDEsIHJlcCgwLjUsIFUpKSkgICAjIEluaXRpYWwgaW5mZWN0ZWQgKGluaXRpYWwgaW5mZWN0ZWQgcGF0Y2ggcmFuZG9tbHkgZ2VuZXJhdGVkKQppbml0aWFsX2luZmVjdGVkX3BhdGNoIDwtIHdoaWNoKGluaXRpYWxfaW5mZWN0ZWQgPiAwKQpzaW1OYW1lIDwtICJTSVJTIG1ldGFwb3B1bGF0aW9uIG1vZGVsIiAgICAgICAjIFNpbXVsYXRpb24gbmFtZQp0ZiA8LSAzNjUqMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBGaW5hbCB0aW1lCgojIEFndGEgSHVudGVyLUdhdGhlcmVyIGNvbnRhY3QgcmF0ZXMKd2l0aGluX3BvcF9jb250YWN0ID0gMQpiZXR3ZWVuX3BvcF9jb250YWN0ID0gMC41L1UgICAgICMgbm9ybWFsaXNlZCBieSBudW1iZXIgb2YgcGF0Y2hlcyAKCiNDcmVhdGUgdGhlIG5hbWVkIGluaXRpYWwgc3RhdGUgdmVjdG9yIGZvciB0aGUgVS1wYXRjaCBzeXN0ZW0uCgp4MF9tZXRhIDwtIHVubGlzdChsYXBwbHkoCiAgc2VxX2xlbihVKSwgCiAgZnVuY3Rpb24oaSl7IAogICAgYyhwYXRjaFBvcFNpemVbaV0gLSBpbml0aWFsX2luZmVjdGVkW2ldLCBpbml0aWFsX2luZmVjdGVkW2ldLCAwLCAwLCBwYXRjaFBvcFNpemVbaV0pCiAgfQopKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbihpKSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCBpKSkpCgoKIyBEZWZpbmUgdGhlIHN0YXRlIGNoYW5nZSBtYXRyaXggZm9yIGEgc2luZ2xlIHBhdGNoCm51X21ldGEgPC0gbWF0cml4KGMoIC0xLCAgMCwgIDAsICsxLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAjIFMKICAgICAgICAgICAgICAgICAgICAgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgLTEsICAwLCAgMCwgIDAsICMgRQogICAgICAgICAgICAgICAgICAgICAgMCwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgLTEsICAwLCAtMSwgIyBJCiAgICAgICAgICAgICAgICAgICAgICAwLCAgMCwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgLTEsICAwLCAjIFIgCiAgICAgICAgICAgICAgICAgICAgICAwLCAgMCwgIDAsICAwLCArMSwgLTEgLC0xLCAtMSwgLTEsIC0xKSwgIyBOCiAgICAgICAgICAgICBucm93PTUsYnlyb3c9VFJVRSkKCiMgRGVmaW5lIHByb3BlbnNpdHkgZnVuY3Rpb25zCiMgTWFzcy1hY3Rpb24KYV9tZXRhIDwtCiAgdW5saXN0KGxhcHBseSgKICAgIHNlcV9sZW4oVSksCiAgICBmdW5jdGlvbihwYXRjaCkgewogICAgICBpIDwtIHBhdGNoCiAgICAgIHBhdGNoZXMgPC0gMTpVCiAgICAgICNqIDwtIGlmIChwYXRjaCA9PSAxKSBVIGVsc2UgcGF0Y2ggLSAxCiAgICAgIG90aGVyX3BhdGNoZXMgPC0gcGF0Y2hlc1staV0KICAgICAgcGF0Y2hfYmV0YSA8LSBjKCkKICAgICAgZm9yKGsgaW4gKDE6KFUtMSkpKXsKICAgICAgICBwYXRjaF9iZXRhW2tdID0gcGFzdGUwKCIrKGJldGFfIiwgb3RoZXJfcGF0Y2hlc1trXSxpLCAiKkkiLCBvdGhlcl9wYXRjaGVzW2tdLCAiL04iLCBvdGhlcl9wYXRjaGVzW2tdLCAiKSpTIiwgaSkKICAgICAgfQogICAgICBjKAogICAgICAgIHBhc3RlMCgiKGJldGFfIiwgaSwgaSwgIipJIiwgaSwiL04iLCBpLCAiKSpTIixpLCBwYXN0ZTAocGF0Y2hfYmV0YSwgY29sbGFwc2U9IiIpKSwgIyBJbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoInNpZ21hKkUiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJlY29tZXMgaW5mZWNpb3VzCiAgICAgICAgcGFzdGUwKCJnYW1tYSpJIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBSZWNvdmVyeSBmcm9tIGluZmVjdGlvbgogICAgICAgIHBhc3RlMCgib21lZ2EqUiIsIGkpLCAgICAgICAjIExvc3Mgb2YgaW1tdW5pdHkKICAgICAgICBwYXN0ZTAoIm11Kk4iLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGhzCiAgICAgICAgcGFzdGUwKCJtdSpTIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFMpCiAgICAgICAgcGFzdGUwKCJtdSpFIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEUpCiAgICAgICAgcGFzdGUwKCJtdSpJIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEkpCiAgICAgICAgcGFzdGUwKCJtdSpSIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFIpCiAgICAgICAgcGFzdGUwKCJhbHBoYSpJIiwgaSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgZnJvbSBpbmZlY3Rpb24KICAgICAgICAKICAgICAgKQogICAgfQogICkpCgpgYGAKCgpEZWZpbmUgZnVuY3Rpb25zIGZvciBjYWxjdWxhdGluZyBSMCBmcm9tIG5leHQtZ2VuZXJhdGlvbiBtYXRyaXgKYGBge3J9CiMgQ2FsY3VsYXRlIFIwIGZyb20gTkdNCgpSMG5nbSA8LSBmdW5jdGlvbihuZXh0Z2VuX21hdHJpeCkgewogIGVpZ2VudmFsdWVzID0gZWlnZW4obmV4dGdlbl9tYXRyaXgsIG9ubHkudmFsdWVzID0gVCkKICBSMCA9IG1heChhYnMoZWlnZW52YWx1ZXMkdmFsdWVzKSkKICByZXR1cm4oUjApCn0KCmJldGEubmdtIDwtIGZ1bmN0aW9uKGJldGFfbWF0cml4KSB7CiAgZWlnZW52YWx1ZXMgPSBlaWdlbihiZXRhX21hdHJpeCwgb25seS52YWx1ZXMgPSBUKQogIGJldGFfbmdtID0gbWF4KGFicyhlaWdlbnZhbHVlcyR2YWx1ZXMpKQogIHJldHVybihiZXRhX25nbSkKfQpgYGAKCgoKIyMjIFJ1biBNZXRhcG9wdWxhdGlvbiBNb2RlbApgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhIDwtIGxpc3QoCiAgc2lnbWEgPSAwLjE3NSwgICAgICAgICAgICAgICAgICAgICAgICAgICMgRSB0byBJIHJhdGUKICBnYW1tYSA9IDAuMiwgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEkgdG8gUiByYXRlCiAgb21lZ2EgPSAxLzEwMCwgICAgICAgICAgICAgICAgICAgICAgICAgIyBSIHRvIFMgcmF0ZQogIG11ID0gZGVtb19zdW0kQmlydGhfcmF0ZV9kYWlseV9NZWFuLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJpcnRoL2RlYXRoIHJhdGUgcGVyIHBlcnNvbiBwZXIgZGF5CiAgYWxwaGEgPSAxLzEwMDApIAoKIyBEZWZpbmUgdHJhbnNtaXNzaW9uIHRlcm1zIGFuZCBwb3B1bGF0ZSBuZXh0LWdlbmVyYXRpb24gbWF0cml4CmJldGEgPC0gMC42CgpuZXh0Z2VuX21hdHJpeCA8LSBtYXRyaXgobnJvdyA9IFUsIG5jb2wgPSBVLCBkYXRhID0gMCkKYmV0YV9tYXRyaXggPC0gbWF0cml4KG5yb3cgPSBVLCBuY29sID0gVSwgZGF0YSA9IDApCgoKZm9yKGkgaW4gMTpVKXsKICBmb3IoaiBpbiAxOlUpewogICAgcGFybXNfbWV0YVtbcGFzdGUwKCJiZXRhXyIsaSxpKV1dID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEKICAgIG5leHRnZW5fbWF0cml4W2ksaV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc19tZXRhJGdhbW1hKQogICAgcGFybXNfbWV0YVtbcGFzdGUwKCJiZXRhXyIsaixpKV1dID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBuZXh0Z2VuX21hdHJpeFtqLGldID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhKigxL3Bhcm1zX21ldGEkZ2FtbWEpCiAgICBuZXh0Z2VuX21hdHJpeFtpLGpdID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhKigxL3Bhcm1zX21ldGEkZ2FtbWEpCiAgICBwYXJtc19tZXRhW1twYXN0ZTAoImJldGFfIixqLGopXV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl9tYXRyaXhbaixqXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhKigxL3Bhcm1zX21ldGEkZ2FtbWEpCiAgICBiZXRhX21hdHJpeFtpLGldID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEKICAgIGJldGFfbWF0cml4W2osaV0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEKICAgIGJldGFfbWF0cml4W2ksal0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEKICAgIGJldGFfbWF0cml4W2osal0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogIH0KICBwYXJtc19tZXRhW1twYXN0ZTAoIk4iLCBpKV1dID0gcGF0Y2hQb3BTaXplW2ldCn0KYGBgCgoKYGBge3J9CiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoMjUpCm91dF9tZXRhIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgUGxvdApwbG90X2RhdGFfbWV0YSA8LSBvdXRfbWV0YSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoYWxwaGE9MC44KSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMSwgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSAoRGF5cykiLAogICAgICAgeT0iTnVtYmVyIG9mIEluZGl2aWR1YWxzIiwKICAgICAgIGNvbG91cj0iU3RhdGUiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YQoKZ2dzYXZlKGZpbGVuYW1lID0gIm1ldGFfcGxvdF83LnBkZiIsIAogICAgICAgcGxvdCA9IHBsb3RfbWV0YSwKICAgICAgIGRldmljZSA9ICJwZGYiLAogICAgICAgd2lkdGggPSA3LCAKICAgICAgIGhlaWdodCA9IDgsCiAgICAgICBwYXRoID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvUGxvdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscyIpCmBgYAoKYGBge3J9CiMjIFRhYmxlIHNob3dpbmcgZXh0aW5jdGlvbi90cmFuc21pc3Npb24gaW5mbyBmb3IgZWFjaCBwYXRjaAoKZXh0aW5jdF9kYXRhX21ldGEgPC0gb3V0X21ldGEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBzbGljZV9tYXgodCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHN0YXRlPT0iSSIgJiBjb3VudCA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZT09IkkiICYgY291bnQgPT0gMCB+IEYpKSAlPiUKICBkcm9wX25hKCkgJT4lCiAgc2VsZWN0KHBhdGNoLCBjb3VudCwgcGVyc2lzdCkKZXh0aW5jdF9kYXRhX21ldGEKYGBgCgoKYGBge3J9CmJldGFfbWV0YSA8LSBiZXRhLm5nbShiZXRhX21hdHJpeCkKcGFzdGUwKCJCZXRhIGZvciB3aG9sZSBzeXN0ZW0gPSAiLCBiZXRhX21ldGEpCgoKUjBfbWV0YSA8LSBSMG5nbShuZXh0Z2VuX21hdHJpeCkKcGFzdGUwKCJSMCA9ICIsIFIwX21ldGEpCgoKcGFzdGUwKCJBY3R1YWwgbnVtYmVyIG9mIGluZmVjdGVkcyBhdCBlbmQgb2Ygc2ltID0gIiwgc3VtKGV4dGluY3RfZGF0YV9tZXRhJGNvdW50KSkKICMgVG90YWwgbnVtYmVyIG9mIGluZmVjdGVkcyBhdCB0aGUgZW5kIG9mIHNpbSBhY3Jvc3MgYWxsIHBhdGNoZXMKCnNpbV9lbmRwb2ludF9tZXRhIDwtIGFzX3RpYmJsZShvdXRfbWV0YSRkYXRhKSAlPiUKICBzbGljZV9tYXgodCkgJT4lCiAgZGlzdGluY3QoKQoKCnBhc3RlMCgiRGlkIHNpbXVsYXRpb24gcnVuIHJlYWNoIGZpbmFsIGVuZHBvaW50PyIpCmlmIChzaW1fZW5kcG9pbnRfbWV0YSR0ID49IHRmKSB7CiAgcHJpbnQoIlllcyIpCn0gZWxzZSB7CiAgcHJpbnQoIk5vIil9CgpgYGAKCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbih4KXsgCiAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICB9CikpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKICAKICBvdXRfMTAwX21ldGEgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGEgPC0gb3V0XzEwMF9tZXRhJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFbW2ldXSA8LSBzaW1fZGF0YV9tZXRhCn0KCnNpbV9vdXRwdXRfbWV0YSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhIDwtIHNpbV9vdXRwdXRfbWV0YSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YQpgYGAKCgoKYGBge3J9CiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhIDwtIHNpbV9vdXRwdXRfbWV0YSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTAwKQpzaW1fc3VtbWFyeV9tZXRhCmBgYAoKCgojIyMgVmFyeWluZyB3YWluaW5nIGltbXVuaXR5IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQojIyMjIDAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzAkb21lZ2EgPC0gMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8wLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMCA8LSBvdXRfbWV0YV8wJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8wLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8wCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8wIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzAgPC0gb3V0XzEwMF9tZXRhXzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8wW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8wCn0KCnNpbV9vdXRwdXRfbWV0YV8wIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8wIDwtIHNpbV9vdXRwdXRfbWV0YV8wICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzAgPC0gc2ltX291dHB1dF9tZXRhXzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAwKQpzaW1fc3VtbWFyeV9tZXRhXzAKYGBgCgoKCiMjIyMgMSBEYXkKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8xIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8xJG9tZWdhIDwtIDEKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzEgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMSwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzEgPC0gb3V0X21ldGFfMSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8xIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMQpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMSA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8xIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzEgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8xLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8xIDwtIG91dF8xMDBfbWV0YV8xJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMVtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMQp9CgpzaW1fb3V0cHV0X21ldGFfMSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8xKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMSA8LSBzaW1fb3V0cHV0X21ldGFfMSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8xCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8xIDwtIHNpbV9vdXRwdXRfbWV0YV8xICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEpCnNpbV9zdW1tYXJ5X21ldGFfMQpgYGAKCgoKCiMjIyMgMyBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMyA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMyRvbWVnYSA8LSAxLzMKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzMgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzMgPC0gb3V0X21ldGFfMyRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8zIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMywgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMwpgYGAKCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzMgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8zIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMyA8LSBvdXRfMTAwX21ldGFfMyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzNbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzMKfQoKc2ltX291dHB1dF9tZXRhXzMgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzMgPC0gc2ltX291dHB1dF9tZXRhXzMgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMyA8LSBzaW1fb3V0cHV0X21ldGFfMyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzMpCnNpbV9zdW1tYXJ5X21ldGFfMwpgYGAKCgoKCgoKIyMjIyA3IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV83IDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV83JG9tZWdhIDwtIDEvNwoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfNyA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV83LAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfNyA8LSBvdXRfbWV0YV83JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzcgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV83LCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV83CmBgYAoKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfNyA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV83IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzcgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV83LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV83IDwtIG91dF8xMDBfbWV0YV83JGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfN1tbaV1dIDwtIHNpbV9kYXRhX21ldGFfNwp9CgpzaW1fb3V0cHV0X21ldGFfNyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV83KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfNyA8LSBzaW1fb3V0cHV0X21ldGFfNyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV83CgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV83IDwtIHNpbV9vdXRwdXRfbWV0YV83ICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNykKc2ltX3N1bW1hcnlfbWV0YV83CmBgYAoKCgojIyMjIDEwIERheXMKCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMTAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzEwJG9tZWdhIDwtIDEvMTAKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMTAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8xMCA8LSBvdXRfbWV0YV8xMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8xMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzEwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8xMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMTAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMTAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8xMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMTAgPC0gb3V0XzEwMF9tZXRhXzEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMTBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzEwCn0KCnNpbV9vdXRwdXRfbWV0YV8xMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8xMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzEwIDwtIHNpbV9vdXRwdXRfbWV0YV8xMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8xMCA8LSBzaW1fb3V0cHV0X21ldGFfMTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xNCkKc2ltX3N1bW1hcnlfbWV0YV8xMApgYGAKCgojIyMjIDIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8yMCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMjAkb21lZ2EgPC0gMS8yMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMjAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMjAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8yMCA8LSBvdXRfbWV0YV8yMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8yMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzIwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8yMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMjAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMjAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8yMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMjAgPC0gb3V0XzEwMF9tZXRhXzIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMjBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzIwCn0KCnNpbV9vdXRwdXRfbWV0YV8yMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8yMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzIwIDwtIHNpbV9vdXRwdXRfbWV0YV8yMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8yMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMjAgPC0gc2ltX291dHB1dF9tZXRhXzIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjApCnNpbV9zdW1tYXJ5X21ldGFfMjAKYGBgCgoKCgoKCiMjIyMgMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzMwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8zMCRvbWVnYSA8LSAxLzMwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8zMCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8zMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzMwIDwtIG91dF9tZXRhXzMwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzMwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzMwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8zMCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8zMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8zMCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzMwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8zMCA8LSBvdXRfMTAwX21ldGFfMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8zMFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMzAKfQoKc2ltX291dHB1dF9tZXRhXzMwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzMwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMzAgPC0gc2ltX291dHB1dF9tZXRhXzMwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzMwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8zMCA8LSBzaW1fb3V0cHV0X21ldGFfMzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzMwKQpzaW1fc3VtbWFyeV9tZXRhXzMwCmBgYAoKCgojIyMjIDQwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV80MCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfNDAkb21lZ2EgPC0gMS80MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfNDAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfNDAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV80MCA8LSBvdXRfbWV0YV80MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV80MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzQwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV80MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfNDAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfNDAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfNDAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV80MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfNDAgPC0gb3V0XzEwMF9tZXRhXzQwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfNDBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzQwCn0KCnNpbV9vdXRwdXRfbWV0YV80MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV80MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzQwIDwtIHNpbV9vdXRwdXRfbWV0YV80MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV80MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfNDAgPC0gc2ltX291dHB1dF9tZXRhXzQwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNDApCnNpbV9zdW1tYXJ5X21ldGFfNDAKYGBgCgoKCgoKCgojIyMjIDUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV81MCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfNTAkb21lZ2EgPC0gMS81MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfNTAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfNTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV81MCA8LSBvdXRfbWV0YV81MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV81MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV81MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfNTAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfNTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfNTAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV81MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfNTAgPC0gb3V0XzEwMF9tZXRhXzUwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfNTBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzUwCn0KCnNpbV9vdXRwdXRfbWV0YV81MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV81MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzUwIDwtIHNpbV9vdXRwdXRfbWV0YV81MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV81MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfNTAgPC0gc2ltX291dHB1dF9tZXRhXzUwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNTApCnNpbV9zdW1tYXJ5X21ldGFfNTAKYGBgCgoKCgoKIyMjIyA2MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfNjAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzYwJG9tZWdhIDwtIDEvNjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzYwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzYwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfNjAgPC0gb3V0X21ldGFfNjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfNjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV82MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfNjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzYwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzYwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzYwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfNjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzYwIDwtIG91dF8xMDBfbWV0YV82MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzYwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV82MAp9CgpzaW1fb3V0cHV0X21ldGFfNjAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfNjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV82MCA8LSBzaW1fb3V0cHV0X21ldGFfNjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfNjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzYwIDwtIHNpbV9vdXRwdXRfbWV0YV82MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzYwKQpzaW1fc3VtbWFyeV9tZXRhXzYwCmBgYAoKCgoKIyMjIyA3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfNzAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzcwJG9tZWdhIDwtIDEvNzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzcwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzcwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfNzAgPC0gb3V0X21ldGFfNzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfNzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV83MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfNzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzcwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzcwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzcwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzcwIDwtIG91dF8xMDBfbWV0YV83MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzcwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV83MAp9CgpzaW1fb3V0cHV0X21ldGFfNzAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfNzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV83MCA8LSBzaW1fb3V0cHV0X21ldGFfNzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfNzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzcwIDwtIHNpbV9vdXRwdXRfbWV0YV83MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcwKQpzaW1fc3VtbWFyeV9tZXRhXzcwCmBgYAoKCiMjIyMgODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzgwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV84MCRvbWVnYSA8LSAxLzgwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV84MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV84MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzgwIDwtIG91dF9tZXRhXzgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzgwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfODAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV84MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV84MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV84MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV84MCA8LSBvdXRfMTAwX21ldGFfODAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV84MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfODAKfQoKc2ltX291dHB1dF9tZXRhXzgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfODAgPC0gc2ltX291dHB1dF9tZXRhXzgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV84MCA8LSBzaW1fb3V0cHV0X21ldGFfODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS84MCkKc2ltX3N1bW1hcnlfbWV0YV84MApgYGAKCgoKIyMjIyA5MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfOTAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzkwJG9tZWdhIDwtIDEvOTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzkwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzkwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfOTAgPC0gb3V0X21ldGFfOTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfOTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV85MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfOTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzkwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzkwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzkwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfOTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzkwIDwtIG91dF8xMDBfbWV0YV85MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzkwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV85MAp9CgpzaW1fb3V0cHV0X21ldGFfOTAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfOTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV85MCA8LSBzaW1fb3V0cHV0X21ldGFfOTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfOTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzkwIDwtIHNpbV9vdXRwdXRfbWV0YV85MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzkwKQpzaW1fc3VtbWFyeV9tZXRhXzkwCmBgYAoKCgoKCgoKIyMjIyAxODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzE4MCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMTgwJG9tZWdhIDwtIDEvMTgwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCgyMCkKb3V0X21ldGFfMTgwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzE4MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzE4MCA8LSBvdXRfbWV0YV8xODAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMTgwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMTgwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8xODAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzE4MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8xODAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMTgwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMTgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8xODAgPC0gb3V0XzEwMF9tZXRhXzE4MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzE4MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMTgwCn0KCnNpbV9vdXRwdXRfbWV0YV8xODAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMTgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMTgwIDwtIHNpbV9vdXRwdXRfbWV0YV8xODAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMTgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8xODAgPC0gc2ltX291dHB1dF9tZXRhXzE4MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE4MCkKc2ltX3N1bW1hcnlfbWV0YV8xODAKYGBgCgojIyMjIDExMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMTEwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8xMTAkb21lZ2EgPC0gMS8xMTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzExMCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8xMTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8xMTAgPC0gb3V0X21ldGFfMTEwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzExMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzExMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMTEwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8xMTAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMTEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzExMCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzExMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMTEwIDwtIG91dF8xMDBfbWV0YV8xMTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8xMTBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzExMAp9CgpzaW1fb3V0cHV0X21ldGFfMTEwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzExMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzExMCA8LSBzaW1fb3V0cHV0X21ldGFfMTEwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzExMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMTEwIDwtIHNpbV9vdXRwdXRfbWV0YV8xMTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMTApCnNpbV9zdW1tYXJ5X21ldGFfMTEwCmBgYAoKIyMjIyAxMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzEyMCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMTIwJG9tZWdhIDwtIDEvMTIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8xMjAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMTIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMTIwIDwtIG91dF9tZXRhXzEyMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8xMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8xMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzEyMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMTIwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzEyMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8xMjAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8xMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzEyMCA8LSBvdXRfMTAwX21ldGFfMTIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMTIwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8xMjAKfQoKc2ltX291dHB1dF9tZXRhXzEyMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8xMjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8xMjAgPC0gc2ltX291dHB1dF9tZXRhXzEyMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8xMjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzEyMCA8LSBzaW1fb3V0cHV0X21ldGFfMTIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTIwKQpzaW1fc3VtbWFyeV9tZXRhXzEyMApgYGAKCiMjIyMgMTMwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8xMzAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzEzMCRvbWVnYSA8LSAxLzEzMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMTMwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzEzMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzEzMCA8LSBvdXRfbWV0YV8xMzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMTMwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMTMwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8xMzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzEzMCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8xMzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMTMwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMTMwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8xMzAgPC0gb3V0XzEwMF9tZXRhXzEzMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzEzMFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMTMwCn0KCnNpbV9vdXRwdXRfbWV0YV8xMzAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMTMwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMTMwIDwtIHNpbV9vdXRwdXRfbWV0YV8xMzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMTMwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8xMzAgPC0gc2ltX291dHB1dF9tZXRhXzEzMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEzMCkKc2ltX3N1bW1hcnlfbWV0YV8xMzAKYGBgCgoKCgoKCgoKCgoKCiMjIyMgMTUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8xNTAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzE1MCRvbWVnYSA8LSAxLzE1MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMTUwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzE1MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzE1MCA8LSBvdXRfbWV0YV8xNTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMTUwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMTUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8xNTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzE1MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8xNTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMTUwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMTUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8xNTAgPC0gb3V0XzEwMF9tZXRhXzE1MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzE1MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMTUwCn0KCnNpbV9vdXRwdXRfbWV0YV8xNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMTUwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMTUwIDwtIHNpbV9vdXRwdXRfbWV0YV8xNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMTUwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8xNTAgPC0gc2ltX291dHB1dF9tZXRhXzE1MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE1MCkKc2ltX3N1bW1hcnlfbWV0YV8xNTAKYGBgCgoKIyMjIyAyMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzIyMCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMjIwJG9tZWdhIDwtIDEvMjIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8yMjAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMjIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMjIwIDwtIG91dF9tZXRhXzIyMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8yMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8yMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzIyMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMjIwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzIyMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8yMjAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8yMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzIyMCA8LSBvdXRfMTAwX21ldGFfMjIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMjIwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8yMjAKfQoKc2ltX291dHB1dF9tZXRhXzIyMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8yMjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8yMjAgPC0gc2ltX291dHB1dF9tZXRhXzIyMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8yMjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzIyMCA8LSBzaW1fb3V0cHV0X21ldGFfMjIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjIwKQpzaW1fc3VtbWFyeV9tZXRhXzIyMApgYGAKCgoKCiMjIyMgMjcwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8yNzAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzI3MCRvbWVnYSA8LSAxLzI3MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMjcwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzI3MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzI3MCA8LSBvdXRfbWV0YV8yNzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMjcwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMjcwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8yNzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzI3MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8yNzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMjcwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMjcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8yNzAgPC0gb3V0XzEwMF9tZXRhXzI3MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzI3MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMjcwCn0KCnNpbV9vdXRwdXRfbWV0YV8yNzAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMjcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMjcwIDwtIHNpbV9vdXRwdXRfbWV0YV8yNzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMjcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8yNzAgPC0gc2ltX291dHB1dF9tZXRhXzI3MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzI3MCkKc2ltX3N1bW1hcnlfbWV0YV8yNzAKYGBgCgojIyMjIDM2NSBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMzY1IDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8zNjUkb21lZ2EgPC0gMS8zNjUKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzM2NSA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8zNjUsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8zNjUgPC0gb3V0X21ldGFfMzY1JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzM2NSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzM2NSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMzY1CmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8zNjUgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMzY1IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzM2NSA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzM2NSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMzY1IDwtIG91dF8xMDBfbWV0YV8zNjUkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8zNjVbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzM2NQp9CgpzaW1fb3V0cHV0X21ldGFfMzY1IDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzM2NSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzM2NSA8LSBzaW1fb3V0cHV0X21ldGFfMzY1ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzM2NQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMzY1IDwtIHNpbV9vdXRwdXRfbWV0YV8zNjUgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zNjUpCnNpbV9zdW1tYXJ5X21ldGFfMzY1CmBgYAoKU2luZ2xlCgoKCgoKIyMjIyBSZXN1bHRzCmBgYHtyfQp3YW5pbmdfcmVzdWx0c183IDwtIHNpbV9zdW1tYXJ5X21ldGEgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfNykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8zMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfNDApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzUwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV82MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfNzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzgwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV85MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMTAwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8xMTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzEyMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMTMwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8xNTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzIyMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMjcwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8zNjUpICU+JQogIG11dGF0ZShpbW11bml0eV9kdXJhdGlvbiA9IDEvb21lZ2EpICU+JQogIGFycmFuZ2UoaW1tdW5pdHlfZHVyYXRpb24pICU+JQogIG11dGF0ZShtb2RlbCA9ICJtZXRhIiwKICAgICAgICAgcGF0Y2hlcyA9IDcpCgp3cml0ZV9jc3Yod2FuaW5nX3Jlc3VsdHNfNywgZmlsZSA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMvUmVzdWx0cy93YW5pbmdfcmVzdWx0c183LmNzdiIpCgp3YW5pbmdfcmVzdWx0c183CgpgYGAKCmBgYHtyfQpnZ3Bsb3Qod2FuaW5nX3Jlc3VsdHNfNywgYWVzKGltbXVuaXR5X2R1cmF0aW9uLCBzdW1fcGVyc2lzdCkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkrCiAgdGhlbWVfYncoKQpgYGAKCgoKCiMjIDMtUGF0Y2ggTWV0YXBvcHVsYXRpb24gTW9kZWwgCgpUaGUgc2FtZSBtZXRhcG9wdWxhdGlvbiBTRUlSUyBtb2RlbCB3YXMgdGhlbiB1c2VkIHRvIG1vZGVsIHRoZSBkeW5hbWljcyBvZiBwZXJzaXN0ZW5jZSBpbiBhIDMtcGF0Y2ggc3lzdGVtIGFuZCB1bmRlcnN0YW5kIHRoZSBlZmZlY3Qgb2Ygd2FuaW5nIGltbXVuaXR5LgoKIyMjU2V0LXVwCgpgYGB7cn0KIyBEZWZpbmUgUGFyYW1lbnRlcnMKcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFBhdGNoIHNpemUKVSA8LSBsZW5ndGgocGF0Y2hQb3BTaXplXzMpICAgICAgICAgICAgICAgICAgICAjIE51bWJlciBvZiBwYXRjaGVzCmluaXRpYWxfaW5mZWN0ZWQgPC0gIGFzLnZlY3RvcihybXVsdGlub20oMSwgMSwgcmVwKDAuNSwgVSkpKSAgICMgSW5pdGlhbCBpbmZlY3RlZCAoaW5pdGlhbCBpbmZlY3RlZCBwYXRjaCByYW5kb21seSBnZW5lcmF0ZWQpCmluaXRpYWxfaW5mZWN0ZWRfcGF0Y2ggPC0gd2hpY2goaW5pdGlhbF9pbmZlY3RlZCA+IDApCnNpbU5hbWUgPC0gIlNJUlMgbWV0YXBvcHVsYXRpb24gbW9kZWwiICAgICAgICMgU2ltdWxhdGlvbiBuYW1lCnRmIDwtIDM2NSozICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEZpbmFsIHRpbWUKCiMgQWd0YSBIdW50ZXItR2F0aGVyZXIgY29udGFjdCByYXRlcwp3aXRoaW5fcG9wX2NvbnRhY3QgPSAxCmJldHdlZW5fcG9wX2NvbnRhY3QgPSAwLjUvVSAgICAgIyBub3JtYWxpc2VkIGJ5IG51bWJlciBvZiBwYXRjaGVzIAoKI0NyZWF0ZSB0aGUgbmFtZWQgaW5pdGlhbCBzdGF0ZSB2ZWN0b3IgZm9yIHRoZSBVLXBhdGNoIHN5c3RlbS4KCngwXzNfbWV0YSA8LSB1bmxpc3QobGFwcGx5KAogIHNlcV9sZW4oVSksIAogIGZ1bmN0aW9uKGkpeyAKICAgIGMocGF0Y2hQb3BTaXplXzNbaV0gLSBpbml0aWFsX2luZmVjdGVkW2ldLCBpbml0aWFsX2luZmVjdGVkW2ldLCAwLCAwLCBwYXRjaFBvcFNpemVfM1tpXSkKICB9CikpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oaSkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgaSkpKQoKCiMgRGVmaW5lIHRoZSBzdGF0ZSBjaGFuZ2UgbWF0cml4IGZvciBhIHNpbmdsZSBwYXRjaApudV8zX21ldGEgPC0gbWF0cml4KGMoIC0xLCAgMCwgIDAsICsxLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAjIFMKICAgICAgICAgICAgICAgICAgICAgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgLTEsICAwLCAgMCwgIDAsICMgRQogICAgICAgICAgICAgICAgICAgICAgMCwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgLTEsICAwLCAtMSwgIyBJCiAgICAgICAgICAgICAgICAgICAgICAwLCAgMCwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgLTEsICAwLCAjIFIgCiAgICAgICAgICAgICAgICAgICAgICAwLCAgMCwgIDAsICAwLCArMSwgLTEgLC0xLCAtMSwgLTEsIC0xKSwgIyBOCiAgICAgICAgICAgICBucm93PTUsYnlyb3c9VFJVRSkKCiMgRGVmaW5lIHByb3BlbnNpdHkgZnVuY3Rpb25zCiMgTWFzcy1hY3Rpb24KYV8zX21ldGEgPC0KICB1bmxpc3QobGFwcGx5KAogICAgc2VxX2xlbihVKSwKICAgIGZ1bmN0aW9uKHBhdGNoKSB7CiAgICAgIGkgPC0gcGF0Y2gKICAgICAgcGF0Y2hlcyA8LSAxOlUKICAgICAgI2ogPC0gaWYgKHBhdGNoID09IDEpIFUgZWxzZSBwYXRjaCAtIDEKICAgICAgb3RoZXJfcGF0Y2hlcyA8LSBwYXRjaGVzWy1pXQogICAgICBwYXRjaF9iZXRhIDwtIGMoKQogICAgICBmb3IoayBpbiAoMTooVS0xKSkpewogICAgICAgIHBhdGNoX2JldGFba10gPSBwYXN0ZTAoIisoYmV0YV8iLCBvdGhlcl9wYXRjaGVzW2tdLGksICIqSSIsIG90aGVyX3BhdGNoZXNba10sICIvTiIsIG90aGVyX3BhdGNoZXNba10sICIpKlMiLCBpKQogICAgICB9CiAgICAgIGMoCiAgICAgICAgcGFzdGUwKCIoYmV0YV8iLCBpLCBpLCAiKkkiLCBpLCIvTiIsIGksICIpKlMiLGksIHBhc3RlMChwYXRjaF9iZXRhLCBjb2xsYXBzZT0iIikpLCAjIEluZmVjdGlvbgogICAgICAgIHBhc3RlMCgic2lnbWEqRSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmVjb21lcyBpbmZlY2lvdXMKICAgICAgICBwYXN0ZTAoImdhbW1hKkkiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFJlY292ZXJ5IGZyb20gaW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJvbWVnYSpSIiwgaSksICAgICAgICMgTG9zcyBvZiBpbW11bml0eQogICAgICAgIHBhc3RlMCgibXUqTiIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aHMKICAgICAgICBwYXN0ZTAoIm11KlMiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUykKICAgICAgICBwYXN0ZTAoIm11KkUiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoRSkKICAgICAgICBwYXN0ZTAoIm11KkkiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoSSkKICAgICAgICBwYXN0ZTAoIm11KlIiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUikKICAgICAgICBwYXN0ZTAoImFscGhhKkkiLCBpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyBmcm9tIGluZmVjdGlvbgogICAgICAgIAogICAgICApCiAgICB9CiAgKSkKCmBgYAoKCgojIyMgUnVuIE1ldGFwb3B1bGF0aW9uIE1vZGVsCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YSA8LSBsaXN0KAogIHNpZ21hID0gMC4xNzUsICAgICAgICAgICAgICAgICAgICAgICAgICAjIEUgdG8gSSByYXRlCiAgZ2FtbWEgPSAwLjIsICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBJIHRvIFIgcmF0ZQogIG9tZWdhID0gMS8xMDAsICAgICAgICAgICAgICAgICAgICAgICAgICMgUiB0byBTIHJhdGUKICBtdSA9IGRlbW9fc3VtJEJpcnRoX3JhdGVfZGFpbHlfTWVhbiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aC9kZWF0aCByYXRlIHBlciBwZXJzb24gcGVyIGRheQogIGFscGhhID0gMS8xMDAwKSAKCiMgRGVmaW5lIHRyYW5zbWlzc2lvbiB0ZXJtcyBhbmQgcG9wdWxhdGUgbmV4dC1nZW5lcmF0aW9uIG1hdHJpeApiZXRhIDwtIDAuNgoKbmV4dGdlbl8zX21hdHJpeCA8LSBtYXRyaXgobnJvdyA9IFUsIG5jb2wgPSBVLCBkYXRhID0gMCkKYmV0YV8zX21hdHJpeCA8LSBtYXRyaXgobnJvdyA9IFUsIG5jb2wgPSBVLCBkYXRhID0gMCkKCgpmb3IoaSBpbiAxOlUpewogIGZvcihqIGluIDE6VSl7CiAgICBwYXJtc18zX21ldGFbW3Bhc3RlMCgiYmV0YV8iLGksaSldXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBuZXh0Z2VuXzNfbWF0cml4W2ksaV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18zX21ldGEkZ2FtbWEpCiAgICBwYXJtc18zX21ldGFbW3Bhc3RlMCgiYmV0YV8iLGosaSldXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl8zX21hdHJpeFtqLGldID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhKigxL3Bhcm1zXzNfbWV0YSRnYW1tYSkKICAgIG5leHRnZW5fM19tYXRyaXhbaSxqXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18zX21ldGEkZ2FtbWEpCiAgICBwYXJtc18zX21ldGFbW3Bhc3RlMCgiYmV0YV8iLGosaildXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBuZXh0Z2VuXzNfbWF0cml4W2osal0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18zX21ldGEkZ2FtbWEpCiAgICBiZXRhXzNfbWF0cml4W2ksaV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV8zX21hdHJpeFtqLGldID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhXzNfbWF0cml4W2ksal0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEKICAgIGJldGFfM19tYXRyaXhbaixqXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgfQogIHBhcm1zXzNfbWV0YVtbcGFzdGUwKCJOIiwgaSldXSA9IHBhdGNoUG9wU2l6ZV8zW2ldCn0KYGBgCgoKYGBge3J9CiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoMjUpCm91dF8zX21ldGEgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YSwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIFBsb3QKcGxvdF9kYXRhXzNfbWV0YSA8LSBvdXRfM19tZXRhJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGEgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoYWxwaGE9MC44KSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMSwgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSAoRGF5cykiLAogICAgICAgeT0iTnVtYmVyIG9mIEluZGl2aWR1YWxzIiwKICAgICAgIGNvbG91cj0iU3RhdGUiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhCgpnZ3NhdmUoZmlsZW5hbWUgPSAibWV0YV9wbG90XzMucGRmIiwgCiAgICAgICBwbG90ID0gcGxvdF8zX21ldGEsCiAgICAgICBkZXZpY2UgPSAicGRmIiwKICAgICAgIHdpZHRoID0gNywgCiAgICAgICBoZWlnaHQgPSA4LAogICAgICAgcGF0aCA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL1Bsb3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMiKQpgYGAKCmBgYHtyfQojIyBUYWJsZSBzaG93aW5nIGV4dGluY3Rpb24vdHJhbnNtaXNzaW9uIGluZm8gZm9yIGVhY2ggcGF0Y2gKCmV4dGluY3RfZGF0YV8zX21ldGEgPC0gb3V0XzNfbWV0YSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHNsaWNlX21heCh0KSAlPiUKICBkaXN0aW5jdCgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSksCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4oc3RhdGU9PSJJIiAmIGNvdW50ID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlPT0iSSIgJiBjb3VudCA9PSAwIH4gRikpICU+JQogIGRyb3BfbmEoKSAlPiUKICBzZWxlY3QocGF0Y2gsIGNvdW50LCBwZXJzaXN0KQpleHRpbmN0X2RhdGFfM19tZXRhCmBgYAoKCmBgYHtyfQpiZXRhXzNfbWV0YSA8LSBiZXRhLm5nbShiZXRhXzNfbWF0cml4KQpwYXN0ZTAoIkJldGEgZm9yIHdob2xlIHN5c3RlbSA9ICIsIGJldGFfM19tZXRhKQoKClIwXzNfbWV0YSA8LSBSMG5nbShuZXh0Z2VuXzNfbWF0cml4KQpwYXN0ZTAoIlIwID0gIiwgUjBfM19tZXRhKQoKCnBhc3RlMCgiQWN0dWFsIG51bWJlciBvZiBpbmZlY3RlZHMgYXQgZW5kIG9mIHNpbSA9ICIsIHN1bShleHRpbmN0X2RhdGFfM19tZXRhJGNvdW50KSkKICMgVG90YWwgbnVtYmVyIG9mIGluZmVjdGVkcyBhdCB0aGUgZW5kIG9mIHNpbSBhY3Jvc3MgYWxsIHBhdGNoZXMKCnNpbV9lbmRwb2ludF8zX21ldGEgPC0gYXNfdGliYmxlKG91dF8zX21ldGEkZGF0YSkgJT4lCiAgc2xpY2VfbWF4KHQpICU+JQogIGRpc3RpbmN0KCkKCgpwYXN0ZTAoIkRpZCBzaW11bGF0aW9uIHJ1biByZWFjaCBmaW5hbCBlbmRwb2ludD8iKQppZiAoc2ltX2VuZHBvaW50XzNfbWV0YSR0ID49IHRmKSB7CiAgcHJpbnQoIlllcyIpCn0gZWxzZSB7CiAgcHJpbnQoIk5vIil9CgpgYGAKCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGEgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QobGFwcGx5KAogIHNlcV9sZW4oVSksIAogIGZ1bmN0aW9uKHgpeyAKICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICB9CikpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQogIAogIG91dF8xMDBfM19tZXRhIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YSA8LSBvdXRfMTAwXzNfbWV0YSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGEKfQoKc2ltX291dHB1dF8zX21ldGEgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGEgPC0gc2ltX291dHB1dF8zX21ldGEgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YQpgYGAKCgoKYGBge3J9CiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGEgPC0gc2ltX291dHB1dF8zX21ldGEgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwMCkKc2ltX3N1bW1hcnlfM19tZXRhCmBgYAoKIyMjIFZhcnlpbmcgd2FpbmluZyBpbW11bml0eSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30KIyMjIyAwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8wJG9tZWdhIDwtIDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzAgPC0gb3V0XzNfbWV0YV8wJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8wCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzAgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV8wIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfMCA8LSBvdXRfMTAwXzNfbWV0YV8wJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8wW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzAKfQoKc2ltX291dHB1dF8zX21ldGFfMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzAgPC0gc2ltX291dHB1dF8zX21ldGFfMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8wICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMCkKc2ltX3N1bW1hcnlfM19tZXRhXzAKYGBgCgoKCiMjIyMgMSBEYXkKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzEgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xJG9tZWdhIDwtIDEKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMSA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzEsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzEgPC0gb3V0XzNfbWV0YV8xJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfMSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzEgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV8xIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzEgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzEsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfMSA8LSBvdXRfMTAwXzNfbWV0YV8xJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8xW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzEKfQoKc2ltX291dHB1dF8zX21ldGFfMSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzEpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzEgPC0gc2ltX291dHB1dF8zX21ldGFfMSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzEKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfMSA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEpCnNpbV9zdW1tYXJ5XzNfbWV0YV8xCmBgYAoKCgoKIyMjIyAzIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzMgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8zJG9tZWdhIDwtIDEvMwoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV8zIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMyA8LSBvdXRfM19tZXRhXzMkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8zIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8zLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzMKYGBgCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzMgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV8zIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzMgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfMyA8LSBvdXRfMTAwXzNfbWV0YV8zJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8zW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzMKfQoKc2ltX291dHB1dF8zX21ldGFfMyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzMpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzMgPC0gc2ltX291dHB1dF8zX21ldGFfMyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzMKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfMyA8LSBzaW1fb3V0cHV0XzNfbWV0YV8zICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMykKc2ltX3N1bW1hcnlfM19tZXRhXzMKYGBgCgoKCgoKCiMjIyMgNyBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV83IDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfNyRvbWVnYSA8LSAxLzcKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfNyA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzcsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzcgPC0gb3V0XzNfbWV0YV83JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfNyA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfNywgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV83CmBgYAoKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV83IDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfNyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV83IDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV83LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzcgPC0gb3V0XzEwMF8zX21ldGFfNyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfN1tbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV83Cn0KCnNpbV9vdXRwdXRfM19tZXRhXzcgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV83KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV83IDwtIHNpbV9vdXRwdXRfM19tZXRhXzcgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV83CgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzcgPC0gc2ltX291dHB1dF8zX21ldGFfNyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcpCnNpbV9zdW1tYXJ5XzNfbWV0YV83CmBgYAoKCgojIyMjIDEwIERheXMKCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xMCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzEwJG9tZWdhIDwtIDEvMTAKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV8xMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzEwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xMCA8LSBvdXRfM19tZXRhXzEwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzEwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzEwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzEwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfMTAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzEwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzEwIDwtIG91dF8xMDBfM19tZXRhXzEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8xMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xMAp9CgpzaW1fb3V0cHV0XzNfbWV0YV8xMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzEwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzEwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzEwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTQpCnNpbV9zdW1tYXJ5XzNfbWV0YV8xMApgYGAKCgojIyMjIDIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzIwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMjAkb21lZ2EgPC0gMS8yMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV8yMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8yMCA8LSBvdXRfM19tZXRhXzIwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzIwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzIwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzIwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfMjAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzIwIDwtIG91dF8xMDBfM19tZXRhXzIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8yMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8yMAp9CgpzaW1fb3V0cHV0XzNfbWV0YV8yMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8yMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8yMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzIwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjApCnNpbV9zdW1tYXJ5XzNfbWV0YV8yMApgYGAKCgoKCgoKIyMjIyAzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8zMCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzMwJG9tZWdhIDwtIDEvMzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMzAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8zMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMzAgPC0gb3V0XzNfbWV0YV8zMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzMwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8zMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8zMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8zMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzMwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzMwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8zMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8zMCA8LSBvdXRfMTAwXzNfbWV0YV8zMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfMzBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMzAKfQoKc2ltX291dHB1dF8zX21ldGFfMzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8zMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMzAgPC0gc2ltX291dHB1dF8zX21ldGFfMzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV8zMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8zMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8zMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzApCnNpbV9zdW1tYXJ5XzNfbWV0YV8zMApgYGAKCgoKIyMjIyA0MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV80MCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzQwJG9tZWdhIDwtIDEvNDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfNDAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV80MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfNDAgPC0gb3V0XzNfbWV0YV80MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzQwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV80MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV80MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV80MCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzQwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzQwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV80MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV80MCA8LSBvdXRfMTAwXzNfbWV0YV80MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfNDBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfNDAKfQoKc2ltX291dHB1dF8zX21ldGFfNDAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV80MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfNDAgPC0gc2ltX291dHB1dF8zX21ldGFfNDAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV80MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV80MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV80MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzQwKQpzaW1fc3VtbWFyeV8zX21ldGFfNDAKYGBgCgoKCgoKCgojIyMjIDUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzUwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfNTAkb21lZ2EgPC0gMS81MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV81MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV81MCA8LSBvdXRfM19tZXRhXzUwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfNTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzUwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzUwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfNTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfNTAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzUwIDwtIG91dF8xMDBfM19tZXRhXzUwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV81MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV81MAp9CgpzaW1fb3V0cHV0XzNfbWV0YV81MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzUwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV81MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV81MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzUwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzUwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzUwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNTApCnNpbV9zdW1tYXJ5XzNfbWV0YV81MApgYGAKCgoKCgojIyMjIDYwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzYwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfNjAkb21lZ2EgPC0gMS82MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV82MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzYwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV82MCA8LSBvdXRfM19tZXRhXzYwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfNjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzYwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzYwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzYwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfNjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfNjAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzYwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzYwIDwtIG91dF8xMDBfM19tZXRhXzYwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV82MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV82MAp9CgpzaW1fb3V0cHV0XzNfbWV0YV82MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzYwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV82MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV82MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzYwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzYwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzYwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNjApCnNpbV9zdW1tYXJ5XzNfbWV0YV82MApgYGAKCgoKCiMjIyMgNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfNzAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV83MCRvbWVnYSA8LSAxLzcwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzcwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfNzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzcwIDwtIG91dF8zX21ldGFfNzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV83MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfNzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfNzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfNzAgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV83MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV83MCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfNzAgPC0gb3V0XzEwMF8zX21ldGFfNzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzcwW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzcwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzcwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfNzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzcwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzcwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfNzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfNzAgPC0gc2ltX291dHB1dF8zX21ldGFfNzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83MCkKc2ltX3N1bW1hcnlfM19tZXRhXzcwCmBgYAoKCiMjIyMgODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfODAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV84MCRvbWVnYSA8LSAxLzgwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzgwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfODAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzgwIDwtIG91dF8zX21ldGFfODAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV84MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfODAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfODAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfODAgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV84MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV84MCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfODAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfODAgPC0gb3V0XzEwMF8zX21ldGFfODAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzgwW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzgwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfODApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzgwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfODAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfODAgPC0gc2ltX291dHB1dF8zX21ldGFfODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS84MCkKc2ltX3N1bW1hcnlfM19tZXRhXzgwCmBgYAoKCgojIyMjIDkwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzkwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfOTAkb21lZ2EgPC0gMS85MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV85MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzkwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV85MCA8LSBvdXRfM19tZXRhXzkwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfOTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzkwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzkwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzkwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfOTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfOTAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzkwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzkwIDwtIG91dF8xMDBfM19tZXRhXzkwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV85MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV85MAp9CgpzaW1fb3V0cHV0XzNfbWV0YV85MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzkwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV85MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV85MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzkwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzkwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzkwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvOTApCnNpbV9zdW1tYXJ5XzNfbWV0YV85MApgYGAKCgoKCgoKCiMjIyMgMTgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzE4MCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzE4MCRvbWVnYSA8LSAxLzE4MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoMjApCm91dF8zX21ldGFfMTgwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMTgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xODAgPC0gb3V0XzNfbWV0YV8xODAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8xODAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzE4MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xODAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMTgwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMTgwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzE4MCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMTgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzE4MCA8LSBvdXRfMTAwXzNfbWV0YV8xODAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzE4MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xODAKfQoKc2ltX291dHB1dF8zX21ldGFfMTgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMTgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xODAgPC0gc2ltX291dHB1dF8zX21ldGFfMTgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMTgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzE4MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xODApCnNpbV9zdW1tYXJ5XzNfbWV0YV8xODAKYGBgCgojIyMjIDExMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xMTAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xMTAkb21lZ2EgPC0gMS8xMTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMTEwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMTEwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xMTAgPC0gb3V0XzNfbWV0YV8xMTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8xMTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzExMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xMTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMTEwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMTEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzExMCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMTEwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzExMCA8LSBvdXRfMTAwXzNfbWV0YV8xMTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzExMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xMTAKfQoKc2ltX291dHB1dF8zX21ldGFfMTEwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMTEwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xMTAgPC0gc2ltX291dHB1dF8zX21ldGFfMTEwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMTEwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzExMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xMTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMTApCnNpbV9zdW1tYXJ5XzNfbWV0YV8xMTAKYGBgCgojIyMjIDEyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xMjAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xMjAkb21lZ2EgPC0gMS8xMjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMTIwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMTIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xMjAgPC0gb3V0XzNfbWV0YV8xMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8xMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzEyMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMTIwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMTIwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzEyMCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMTIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzEyMCA8LSBvdXRfMTAwXzNfbWV0YV8xMjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzEyMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xMjAKfQoKc2ltX291dHB1dF8zX21ldGFfMTIwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMTIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xMjAgPC0gc2ltX291dHB1dF8zX21ldGFfMTIwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMTIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzEyMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xMjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMjApCnNpbV9zdW1tYXJ5XzNfbWV0YV8xMjAKYGBgCgojIyMjIDEzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xMzAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xMzAkb21lZ2EgPC0gMS8xMzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMTMwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMTMwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xMzAgPC0gb3V0XzNfbWV0YV8xMzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8xMzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzEzMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xMzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMTMwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMTMwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzEzMCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMTMwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzEzMCA8LSBvdXRfMTAwXzNfbWV0YV8xMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzEzMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xMzAKfQoKc2ltX291dHB1dF8zX21ldGFfMTMwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMTMwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xMzAgPC0gc2ltX291dHB1dF8zX21ldGFfMTMwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMTMwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzEzMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xMzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMzApCnNpbV9zdW1tYXJ5XzNfbWV0YV8xMzAKYGBgCgoKCgoKCgoKCgoKCiMjIyMgMTUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzE1MCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzE1MCRvbWVnYSA8LSAxLzE1MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV8xNTAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8xNTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzE1MCA8LSBvdXRfM19tZXRhXzE1MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzE1MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfMTUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzE1MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8xNTAgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV8xNTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfMTUwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8xNTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfMTUwIDwtIG91dF8xMDBfM19tZXRhXzE1MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfMTUwW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzE1MAp9CgpzaW1fb3V0cHV0XzNfbWV0YV8xNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8xNTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzE1MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV8xNTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfMTUwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzE1MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE1MCkKc2ltX3N1bW1hcnlfM19tZXRhXzE1MApgYGAKCgojIyMjIDIyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8yMjAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8yMjAkb21lZ2EgPC0gMS8yMjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMjIwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMjIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8yMjAgPC0gb3V0XzNfbWV0YV8yMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8yMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzIyMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8yMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMjIwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMjIwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzIyMCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMjIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzIyMCA8LSBvdXRfMTAwXzNfbWV0YV8yMjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzIyMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8yMjAKfQoKc2ltX291dHB1dF8zX21ldGFfMjIwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMjIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8yMjAgPC0gc2ltX291dHB1dF8zX21ldGFfMjIwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMjIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzIyMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8yMjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yMjApCnNpbV9zdW1tYXJ5XzNfbWV0YV8yMjAKYGBgCgoKCgojIyMjIDI3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8yNzAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8yNzAkb21lZ2EgPC0gMS8yNzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMjcwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMjcwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8yNzAgPC0gb3V0XzNfbWV0YV8yNzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8yNzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzI3MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8yNzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMjcwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMjcwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzI3MCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMjcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzI3MCA8LSBvdXRfMTAwXzNfbWV0YV8yNzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzI3MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8yNzAKfQoKc2ltX291dHB1dF8zX21ldGFfMjcwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMjcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8yNzAgPC0gc2ltX291dHB1dF8zX21ldGFfMjcwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMjcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzI3MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8yNzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yNzApCnNpbV9zdW1tYXJ5XzNfbWV0YV8yNzAKYGBgCgojIyMjIDM2NSBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8zNjUgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8zNjUkb21lZ2EgPC0gMS8zNjUKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMzY1IDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMzY1LAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8zNjUgPC0gb3V0XzNfbWV0YV8zNjUkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8zNjUgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzM2NSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8zNjUKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMzY1IDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMzY1IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzM2NSA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMzY1LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzM2NSA8LSBvdXRfMTAwXzNfbWV0YV8zNjUkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzM2NVtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8zNjUKfQoKc2ltX291dHB1dF8zX21ldGFfMzY1IDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMzY1KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8zNjUgPC0gc2ltX291dHB1dF8zX21ldGFfMzY1ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMzY1CgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzM2NSA8LSBzaW1fb3V0cHV0XzNfbWV0YV8zNjUgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zNjUpCnNpbV9zdW1tYXJ5XzNfbWV0YV8zNjUKYGBgCgpTaW5nbGUKCgoKCgojIyMjIFJlc3VsdHMKYGBge3J9CndhbmluZ19yZXN1bHRzXzMgPC0gc2ltX3N1bW1hcnlfM19tZXRhICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfMykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV83KSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzMwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzQwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzUwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzYwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzcwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzgwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzkwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzE4MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8xMTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfMTIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzEzMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8xNTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfMjIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzI3MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8zNjUpICU+JQogIG11dGF0ZShpbW11bml0eV9kdXJhdGlvbiA9IDEvb21lZ2EpICU+JQogIGFycmFuZ2UoaW1tdW5pdHlfZHVyYXRpb24pICU+JQogIG11dGF0ZShtb2RlbCA9ICJtZXRhIiwKICAgICAgICAgcGF0Y2hlcyA9IDMpCgp3cml0ZV9jc3Yod2FuaW5nX3Jlc3VsdHNfMywgZmlsZSA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMvUmVzdWx0cy93YW5pbmdfcmVzdWx0c18zLmNzdiIpCgp3YW5pbmdfcmVzdWx0c18zCgpgYGAKCmBgYHtyfQpnZ3Bsb3Qod2FuaW5nX3Jlc3VsdHNfMywgYWVzKGltbXVuaXR5X2R1cmF0aW9uLCBzdW1fcGVyc2lzdCkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkrCiAgdGhlbWVfYncoKQpgYGAKCgoKCgoKIyMgMTQgTWV0YXBvcHVsYXRpb24gTW9kZWwgCgpUaGUgc2FtZSBtZXRhcG9wdWxhdGlvbiBTRUlSUyBtb2RlbCB3YXMgdGhlbiB1c2VkIHRvIG1vZGVsIHRoZSBkeW5hbWljcyBvZiBwZXJzaXN0ZW5jZSBpbiBhIDE0LXBhdGNoIHN5c3RlbSBhbmQgdW5kZXJzdGFuZCB0aGUgZWZmZWN0IG9mIHdhbmluZyBpbW11bml0eS4KCgojIyNTZXQtdXAKCmBgYHtyfQojIERlZmluZSBQYXJhbWVudGVycwpwYXRjaFBvcFNpemVfMTQgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBQYXRjaCBzaXplClUgPC0gbGVuZ3RoKHBhdGNoUG9wU2l6ZV8xNCkgICAgICAgICAgICAgICAgICAgICMgTnVtYmVyIG9mIHBhdGNoZXMKaW5pdGlhbF9pbmZlY3RlZCA8LSAgYXMudmVjdG9yKHJtdWx0aW5vbSgxLCAxLCByZXAoMC41LCBVKSkpICAgIyBJbml0aWFsIGluZmVjdGVkIChpbml0aWFsIGluZmVjdGVkIHBhdGNoIHJhbmRvbWx5IGdlbmVyYXRlZCkKaW5pdGlhbF9pbmZlY3RlZF9wYXRjaCA8LSB3aGljaChpbml0aWFsX2luZmVjdGVkID4gMCkKc2ltTmFtZSA8LSAiU0lSUyBtZXRhcG9wdWxhdGlvbiBtb2RlbCIgICAgICAgIyBTaW11bGF0aW9uIG5hbWUKdGYgPC0gMzY1KjMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRmluYWwgdGltZQoKIyBBZ3RhIEh1bnRlci1HYXRoZXJlciBjb250YWN0IHJhdGVzCndpdGhpbl9wb3BfY29udGFjdCA9IDEKYmV0d2Vlbl9wb3BfY29udGFjdCA9IDAuNS9VICAgICAjIG5vcm1hbGlzZWQgYnkgbnVtYmVyIG9mIHBhdGNoZXMgCgojQ3JlYXRlIHRoZSBuYW1lZCBpbml0aWFsIHN0YXRlIHZlY3RvciBmb3IgdGhlIFUtcGF0Y2ggc3lzdGVtLgoKeDBfMTRfbWV0YSA8LSB1bmxpc3QobGFwcGx5KAogIHNlcV9sZW4oVSksIAogIGZ1bmN0aW9uKGkpeyAKICAgIGMocGF0Y2hQb3BTaXplXzE0W2ldIC0gaW5pdGlhbF9pbmZlY3RlZFtpXSwgaW5pdGlhbF9pbmZlY3RlZFtpXSwgMCwgMCwgcGF0Y2hQb3BTaXplXzE0W2ldKQogIH0KKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oaSkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgaSkpKQoKCiMgRGVmaW5lIHRoZSBzdGF0ZSBjaGFuZ2UgbWF0cml4IGZvciBhIHNpbmdsZSBwYXRjaApudV8xNF9tZXRhIDwtIG1hdHJpeChjKCAtMSwgIDAsICAwLCArMSwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgIyBTCiAgICAgICAgICAgICAgICAgICAgICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIDAsICAwLCAjIEUKICAgICAgICAgICAgICAgICAgICAgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgLTEsICMgSQogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIyBSIAogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICAwLCAgMCwgKzEsIC0xICwtMSwgLTEsIC0xLCAtMSksICMgTgogICAgICAgICAgICAgbnJvdz01LGJ5cm93PVRSVUUpCgojIERlZmluZSBwcm9wZW5zaXR5IGZ1bmN0aW9ucwojIE1hc3MtYWN0aW9uCmFfMTRfbWV0YSA8LQogIHVubGlzdChsYXBwbHkoCiAgICBzZXFfbGVuKFUpLAogICAgZnVuY3Rpb24ocGF0Y2gpIHsKICAgICAgaSA8LSBwYXRjaAogICAgICBwYXRjaGVzIDwtIDE6VQogICAgICAjaiA8LSBpZiAocGF0Y2ggPT0gMSkgVSBlbHNlIHBhdGNoIC0gMQogICAgICBvdGhlcl9wYXRjaGVzIDwtIHBhdGNoZXNbLWldCiAgICAgIHBhdGNoX2JldGEgPC0gYygpCiAgICAgIGZvcihrIGluICgxOihVLTEpKSl7CiAgICAgICAgcGF0Y2hfYmV0YVtrXSA9IHBhc3RlMCgiKyhiZXRhXyIsIG90aGVyX3BhdGNoZXNba10saSwgIipJIiwgb3RoZXJfcGF0Y2hlc1trXSwgIi9OIiwgb3RoZXJfcGF0Y2hlc1trXSwgIikqUyIsIGkpCiAgICAgIH0KICAgICAgYygKICAgICAgICBwYXN0ZTAoIihiZXRhXyIsIGksIGksICIqSSIsIGksIi9OIiwgaSwgIikqUyIsaSwgcGFzdGUwKHBhdGNoX2JldGEsIGNvbGxhcHNlPSIiKSksICMgSW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJzaWdtYSpFIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCZWNvbWVzIGluZmVjaW91cwogICAgICAgIHBhc3RlMCgiZ2FtbWEqSSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgUmVjb3ZlcnkgZnJvbSBpbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoIm9tZWdhKlIiLCBpKSwgICAgICAgIyBMb3NzIG9mIGltbXVuaXR5CiAgICAgICAgcGFzdGUwKCJtdSpOIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJpcnRocwogICAgICAgIHBhc3RlMCgibXUqUyIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChTKQogICAgICAgIHBhc3RlMCgibXUqRSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChFKQogICAgICAgIHBhc3RlMCgibXUqSSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChJKQogICAgICAgIHBhc3RlMCgibXUqUiIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChSKQogICAgICAgIHBhc3RlMCgiYWxwaGEqSSIsIGkpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIGZyb20gaW5mZWN0aW9uCiAgICAgICAgCiAgICAgICkKICAgIH0KICApKQoKYGBgCgoKCiMjIyBSdW4gTWV0YXBvcHVsYXRpb24gTW9kZWwKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YSA8LSBsaXN0KAogIHNpZ21hID0gMC4xNzUsICAgICAgICAgICAgICAgICAgICAgICAgICAjIEUgdG8gSSByYXRlCiAgZ2FtbWEgPSAwLjIsICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBJIHRvIFIgcmF0ZQogIG9tZWdhID0gMS8xMDAsICAgICAgICAgICAgICAgICAgICAgICAgICMgUiB0byBTIHJhdGUKICBtdSA9IGRlbW9fc3VtJEJpcnRoX3JhdGVfZGFpbHlfTWVhbiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aC9kZWF0aCByYXRlIHBlciBwZXJzb24gcGVyIGRheQogIGFscGhhID0gMS8xMDAwKSAKCiMgRGVmaW5lIHRyYW5zbWlzc2lvbiB0ZXJtcyBhbmQgcG9wdWxhdGUgbmV4dC1nZW5lcmF0aW9uIG1hdHJpeApiZXRhIDwtIDAuNgoKbmV4dGdlbl8xNF9tYXRyaXggPC0gbWF0cml4KG5yb3cgPSBVLCBuY29sID0gVSwgZGF0YSA9IDApCmJldGFfMTRfbWF0cml4IDwtIG1hdHJpeChucm93ID0gVSwgbmNvbCA9IFUsIGRhdGEgPSAwKQoKCmZvcihpIGluIDE6VSl7CiAgZm9yKGogaW4gMTpVKXsKICAgIHBhcm1zXzE0X21ldGFbW3Bhc3RlMCgiYmV0YV8iLGksaSldXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBuZXh0Z2VuXzE0X21hdHJpeFtpLGldID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfMTRfbWV0YSRnYW1tYSkKICAgIHBhcm1zXzE0X21ldGFbW3Bhc3RlMCgiYmV0YV8iLGosaSldXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl8xNF9tYXRyaXhbaixpXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18xNF9tZXRhJGdhbW1hKQogICAgbmV4dGdlbl8xNF9tYXRyaXhbaSxqXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18xNF9tZXRhJGdhbW1hKQogICAgcGFybXNfMTRfbWV0YVtbcGFzdGUwKCJiZXRhXyIsaixqKV1dID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEKICAgIG5leHRnZW5fMTRfbWF0cml4W2osal0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18xNF9tZXRhJGdhbW1hKQogICAgYmV0YV8xNF9tYXRyaXhbaSxpXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhXzE0X21hdHJpeFtqLGldID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhXzE0X21hdHJpeFtpLGpdID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhXzE0X21hdHJpeFtqLGpdID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEKICB9CiAgcGFybXNfMTRfbWV0YVtbcGFzdGUwKCJOIiwgaSldXSA9IHBhdGNoUG9wU2l6ZV8xNFtpXQp9CmBgYAoKCmBgYHtyfQojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDI1KQpvdXRfMTRfbWV0YSA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YSwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIFBsb3QKcGxvdF9kYXRhXzE0X21ldGEgPC0gb3V0XzE0X21ldGEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGEgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKGFscGhhPTAuOCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUgKERheXMpIiwKICAgICAgIHk9Ik51bWJlciBvZiBJbmRpdmlkdWFscyIsCiAgICAgICBjb2xvdXI9IlN0YXRlIikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGEKCmdnc2F2ZShmaWxlbmFtZSA9ICJtZXRhXzE0X3Bsb3QucGRmIiwgCiAgICAgICBwbG90ID0gcGxvdF8xNF9tZXRhLAogICAgICAgZGV2aWNlID0gInBkZiIsCiAgICAgICB3aWR0aCA9IDcsIAogICAgICAgaGVpZ2h0ID0gOCwKICAgICAgIHBhdGggPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9QbG90cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzIikKYGBgCgpgYGB7cn0KIyMgVGFibGUgc2hvd2luZyBleHRpbmN0aW9uL3RyYW5zbWlzc2lvbiBpbmZvIGZvciBlYWNoIHBhdGNoCgpleHRpbmN0X2RhdGFfMTRfbWV0YSA8LSBvdXRfMTRfbWV0YSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHNsaWNlX21heCh0KSAlPiUKICBkaXN0aW5jdCgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSksCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4oc3RhdGU9PSJJIiAmIGNvdW50ID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlPT0iSSIgJiBjb3VudCA9PSAwIH4gRikpICU+JQogIGRyb3BfbmEoKSAlPiUKICBzZWxlY3QocGF0Y2gsIGNvdW50LCBwZXJzaXN0KQpleHRpbmN0X2RhdGFfMTRfbWV0YQpgYGAKCgpgYGB7cn0KYmV0YV8xNF9tZXRhIDwtIGJldGEubmdtKGJldGFfMTRfbWF0cml4KQpwYXN0ZTAoIkJldGEgZm9yIHdob2xlIHN5c3RlbSA9ICIsIGJldGFfMTRfbWV0YSkKCgpSMF8xNF9tZXRhIDwtIFIwbmdtKG5leHRnZW5fMTRfbWF0cml4KQpwYXN0ZTAoIlIwID0gIiwgUjBfMTRfbWV0YSkKCgpwYXN0ZTAoIkFjdHVhbCBudW1iZXIgb2YgaW5mZWN0ZWRzIGF0IGVuZCBvZiBzaW0gPSAiLCBzdW0oZXh0aW5jdF9kYXRhXzE0X21ldGEkY291bnQpKQogIyBUb3RhbCBudW1iZXIgb2YgaW5mZWN0ZWRzIGF0IHRoZSBlbmQgb2Ygc2ltIGFjcm9zcyBhbGwgcGF0Y2hlcwoKc2ltX2VuZHBvaW50XzE0X21ldGEgPC0gYXNfdGliYmxlKG91dF8xNF9tZXRhJGRhdGEpICU+JQogIHNsaWNlX21heCh0KSAlPiUKICBkaXN0aW5jdCgpCgoKcGFzdGUwKCJEaWQgc2ltdWxhdGlvbiBydW4gcmVhY2ggZmluYWwgZW5kcG9pbnQ/IikKaWYgKHNpbV9lbmRwb2ludF8xNF9tZXRhJHQgPj0gdGYpIHsKICBwcmludCgiWWVzIikKfSBlbHNlIHsKICBwcmludCgiTm8iKX0KCmBgYAoKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGEgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGEgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMTQgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbih4KXsgCiAgICBjKHBhdGNoUG9wU2l6ZV8xNFt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8xNFt4XSkKICB9CikpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKICAKICBvdXRfMTAwXzE0X21ldGEgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGEgPC0gb3V0XzEwMF8xNF9tZXRhJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhCn0KCnNpbV9vdXRwdXRfMTRfbWV0YSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhIDwtIHNpbV9vdXRwdXRfMTRfbWV0YSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YQpgYGAKCgoKYGBge3J9CiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhIDwtIHNpbV9vdXRwdXRfMTRfbWV0YSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTAwKQpzaW1fc3VtbWFyeV8xNF9tZXRhCmBgYAoKIyMjIFZhcnlpbmcgd2FpbmluZyBpbW11bml0eSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30KIyMjIyAwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8wIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8wJG9tZWdhIDwtIDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzAgPC0gb3V0XzE0X21ldGFfMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8wIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8wIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8wIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMCA8LSBvdXRfMTAwXzE0X21ldGFfMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMApgYGAKCgojIyMjIDEwIERheXMKCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMTAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzEwJG9tZWdhIDwtIDEvMTAKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMTAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8xMCA8LSBvdXRfMTRfbWV0YV8xMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8xMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzEwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8xMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMTAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzEwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzEwIDwtIG91dF8xMDBfMTRfbWV0YV8xMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzEwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8xMAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8xMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzEwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMTAKYGBgCgoKIyMjIyAyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMjAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzIwJG9tZWdhIDwtIDEvMjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzIwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMjAgPC0gb3V0XzE0X21ldGFfMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8yMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzIwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzIwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8yMCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8yMCA8LSBvdXRfMTAwXzE0X21ldGFfMjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8yMFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMjAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzIwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMjAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzIwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8yMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yMCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8yMApgYGAKCgoKCgoKIyMjIyAzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMzAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzMwJG9tZWdhIDwtIDEvMzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzMwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzMwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMzAgPC0gb3V0XzE0X21ldGFfMzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8zMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzMwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzMwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8zMCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzMwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8zMCA8LSBvdXRfMTAwXzE0X21ldGFfMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8zMFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMzAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzMwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzMwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzMwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzMwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8zMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzMwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzMwCmBgYAoKCgojIyMjIDQwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV80MCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfNDAkb21lZ2EgPC0gMS80MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfNDAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfNDAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV80MCA8LSBvdXRfMTRfbWV0YV80MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV80MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzQwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV80MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfNDAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfNDAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzQwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfNDAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzQwIDwtIG91dF8xMDBfMTRfbWV0YV80MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzQwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV80MAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfNDAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfNDApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV80MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfNDAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfNDAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzQwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV80MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzQwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzQwCmBgYAoKCgoKCgoKIyMjIyA1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfNTAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzUwJG9tZWdhIDwtIDEvNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzUwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfNTAgPC0gb3V0XzE0X21ldGFfNTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfNTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV81MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfNTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzUwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV81MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV81MCA8LSBvdXRfMTAwXzE0X21ldGFfNTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV81MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfNTAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzUwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzUwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfNTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzUwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzUwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV81MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfNTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS81MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV81MApgYGAKCgoKCgojIyMjIDYwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV82MCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfNjAkb21lZ2EgPC0gMS82MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfNjAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfNjAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV82MCA8LSBvdXRfMTRfbWV0YV82MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV82MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzYwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV82MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfNjAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfNjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzYwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfNjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzYwIDwtIG91dF8xMDBfMTRfbWV0YV82MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzYwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV82MAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfNjAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfNjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV82MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfNjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfNjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzYwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV82MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzYwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzYwCmBgYAoKCgoKIyMjIyA3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfNzAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzcwJG9tZWdhIDwtIDEvNzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzcwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzcwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfNzAgPC0gb3V0XzE0X21ldGFfNzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfNzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV83MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfNzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzcwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzcwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV83MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV83MCA8LSBvdXRfMTAwXzE0X21ldGFfNzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV83MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfNzAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzcwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfNzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzcwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV83MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfNzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV83MApgYGAKCgojIyMjIDgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV84MCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfODAkb21lZ2EgPC0gMS84MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfODAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfODAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV84MCA8LSBvdXRfMTRfbWV0YV84MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV84MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzgwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV84MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfODAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfODAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzgwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfODAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzgwIDwtIG91dF8xMDBfMTRfbWV0YV84MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzgwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV84MAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfODAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfODApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV84MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfODAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfODAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzgwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV84MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzgwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzgwCmBgYAoKCgojIyMjIDkwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV85MCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfOTAkb21lZ2EgPC0gMS85MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfOTAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfOTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV85MCA8LSBvdXRfMTRfbWV0YV85MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV85MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzkwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV85MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfOTAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfOTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzkwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfOTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzkwIDwtIG91dF8xMDBfMTRfbWV0YV85MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzkwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV85MAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfOTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfOTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV85MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfOTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfOTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzkwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV85MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzkwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzkwCmBgYAoKCgoKCgoKIyMjIyAxODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzE4MCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMTgwJG9tZWdhIDwtIDEvMTgwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCgyMCkKb3V0XzE0X21ldGFfMTgwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzE4MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzE4MCA8LSBvdXRfMTRfbWV0YV8xODAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMTgwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMTgwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8xODAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzE4MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8xODAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzE4MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzE4MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMTgwIDwtIG91dF8xMDBfMTRfbWV0YV8xODAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8xODBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzE4MAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMTgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzE4MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzE4MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzE4MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMTgwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xODApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMTgwCmBgYAoKIyMjIyAxMTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzExMCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMTEwJG9tZWdhIDwtIDEvMTEwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8xMTAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTEwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMTEwIDwtIG91dF8xNF9tZXRhXzExMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8xMTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8xMTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzExMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMTEwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzExMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMTEwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTEwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8xMTAgPC0gb3V0XzEwMF8xNF9tZXRhXzExMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzExMFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMTEwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8xMTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMTEwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMTEwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xMTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMTEwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8xMTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzExMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzExMCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8xMTAKYGBgCgojIyMjIDEyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMTIwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8xMjAkb21lZ2EgPC0gMS8xMjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzEyMCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xMjAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8xMjAgPC0gb3V0XzE0X21ldGFfMTIwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzEyMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzEyMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMTIwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8xMjAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMTIwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8xMjAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzEyMCA8LSBvdXRfMTAwXzE0X21ldGFfMTIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMTIwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8xMjAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzEyMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8xMjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8xMjAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzEyMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8xMjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzEyMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTIwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzEyMApgYGAKCiMjIyMgMTMwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8xMzAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzEzMCRvbWVnYSA8LSAxLzEzMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMTMwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzEzMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzEzMCA8LSBvdXRfMTRfbWV0YV8xMzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMTMwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMTMwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8xMzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzEzMCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8xMzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzEzMCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzEzMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMTMwIDwtIG91dF8xMDBfMTRfbWV0YV8xMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8xMzBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzEzMAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMTMwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzEzMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzEzMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTMwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzEzMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMTMwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xMzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMzApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMTMwCmBgYAoKCgoKCgoKCgoKCgojIyMjIDE1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMTUwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8xNTAkb21lZ2EgPC0gMS8xNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzE1MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xNTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8xNTAgPC0gb3V0XzE0X21ldGFfMTUwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzE1MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzE1MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMTUwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8xNTAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMTUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8xNTAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xNTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzE1MCA8LSBvdXRfMTAwXzE0X21ldGFfMTUwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMTUwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8xNTAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzE1MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8xNTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8xNTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzE1MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8xNTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzE1MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTUwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTUwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzE1MApgYGAKCgojIyMjIDIyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMjIwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8yMjAkb21lZ2EgPC0gMS8yMjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzIyMCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8yMjAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8yMjAgPC0gb3V0XzE0X21ldGFfMjIwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzIyMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzIyMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMjIwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8yMjAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMjIwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8yMjAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8yMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzIyMCA8LSBvdXRfMTAwXzE0X21ldGFfMjIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMjIwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8yMjAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzIyMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8yMjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8yMjAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzIyMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8yMjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzIyMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMjIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjIwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzIyMApgYGAKCgoKCiMjIyMgMjcwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8yNzAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzI3MCRvbWVnYSA8LSAxLzI3MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMjcwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzI3MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzI3MCA8LSBvdXRfMTRfbWV0YV8yNzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMjcwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMjcwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8yNzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzI3MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8yNzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzI3MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzI3MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMjcwIDwtIG91dF8xMDBfMTRfbWV0YV8yNzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8yNzBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzI3MAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMjcwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzI3MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzI3MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMjcwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzI3MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMjcwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8yNzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yNzApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMjcwCmBgYAoKIyMjIyAzNjUgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzM2NSA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMzY1JG9tZWdhIDwtIDEvMzY1CgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8zNjUgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMzY1LAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMzY1IDwtIG91dF8xNF9tZXRhXzM2NSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8zNjUgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8zNjUsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzM2NQpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMzY1IDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzM2NSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMzY1IDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMzY1LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8zNjUgPC0gb3V0XzEwMF8xNF9tZXRhXzM2NSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzM2NVtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMzY1Cn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8zNjUgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMzY1KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMzY1IDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8zNjUgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMzY1CgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8zNjUgPC0gc2ltX291dHB1dF8xNF9tZXRhXzM2NSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzM2NSkKc2ltX3N1bW1hcnlfMTRfbWV0YV8zNjUKYGBgCgoKCgoKIyMjIyBSZXN1bHRzCmBgYHtyfQp3YW5pbmdfcmVzdWx0c18xNCA8LSBzaW1fc3VtbWFyeV8xNF9tZXRhICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8yMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzQwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV81MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfNjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzcwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV84MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfOTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzE4MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMTEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8xMjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzEzMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMTUwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8yMjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzI3MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMzY1KSAlPiUKICBtdXRhdGUoaW1tdW5pdHlfZHVyYXRpb24gPSAxL29tZWdhKSAlPiUKICBhcnJhbmdlKGltbXVuaXR5X2R1cmF0aW9uKSAlPiUKICBtdXRhdGUobW9kZWwgPSAibWV0YSIsCiAgICAgICAgIHBhdGNoZXMgPSAxNCkKCndyaXRlX2Nzdih3YW5pbmdfcmVzdWx0c18xNCwgZmlsZSA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMvUmVzdWx0cy93YW5pbmdfcmVzdWx0c18xNC5jc3YiKQoKd2FuaW5nX3Jlc3VsdHNfMTQKCmBgYAoKYGBge3J9CmdncGxvdCh3YW5pbmdfcmVzdWx0c18xNCwgYWVzKGltbXVuaXR5X2R1cmF0aW9uLCBzdW1fcGVyc2lzdCkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkrCiAgdGhlbWVfYncoKQpgYGAKCgojIyBDb21iaW5lZCBSZXN1bHRzCgpSZXN1bHRzIGZyb20gc2luYWxlIGFuZCBtZXRhcG9wdWxhdGlvbiBtb2RlbHMgd2VyZSBjb21pbmVkIGludG8gb25lIGRhdGEgZnJhbWUgYW5kIHZpc3VhbGlzZWQuIAoKYGBge3J9CmNvbWJpbmVkX3dhbmluZyA8LSB3YW5pbmdfcmVzdWx0cyAlPiUKICBiaW5kX3Jvd3Mod2FuaW5nX3Jlc3VsdHNfc2luZ2xlKSAlPiUKICBiaW5kX3Jvd3Mod2FuaW5nX3Jlc3VsdHNfNykgJT4lCiAgYmluZF9yb3dzKHdhbmluZ19yZXN1bHRzXzMpICU+JQogIGJpbmRfcm93cyh3YW5pbmdfcmVzdWx0c18xNCkKCmhlYWQoY29tYmluZWRfd2FuaW5nKQoKCiN3cml0ZV9jc3YoY29tYmluZWRfd2FuaW5nLCBmaWxlID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscy9SZXN1bHRzL2NvbWJpbmVkX3dhbmluZ19yZXN1bHRzLmNzdiIpCgpgYGAKCgpgYGB7cn0KY29tYmluZWRfcGxvdCA8LSBnZ3Bsb3QoY29tYmluZWRfd2FuaW5nLCBhZXMoaW1tdW5pdHlfZHVyYXRpb24sIHN1bV9wZXJzaXN0LCBjb2xvdXIgPSBhcy5mYWN0b3IocGF0Y2hlcykpKSsKICBnZW9tX2xpbmUoYWxwaGE9MC43LCBzaXplPTEpKwogIGdlb21fcG9pbnQoYWxwaGE9MC41LCBzaXplPTIpKwogIGdlb21fc2VnbWVudCh4ID0gLUluZiwgeSA9IDUwLCB4ZW5kID0gMTQxLjUsIHllbmQgPSA1MCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSA1LCB5ID0gNTAsIHhlbmQgPSA1LCB5ZW5kID0gLUluZiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSA0Mi41LCB5ID0gNTAsIHhlbmQgPSA0Mi41LCB5ZW5kID0gLUluZiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSA5MS41LCB5ID0gNTAsIHhlbmQgPSA5MS41LCB5ZW5kID0gLUluZiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSAxNDEuNSwgeSA9IDUwLCB4ZW5kID0gMTQxLjUsIHllbmQgPSAtSW5mLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvdXIgPSAiZ3JleSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMTApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAzNjAsIDUwKSkgKwogIGxhYnMoeCA9ICJEdXJhdGlvbiBvZiBpbW11bml0eSAoZGF5cykiLAogICAgICAgeSA9ICJQcm9iYWJpbGl0eSBvZiBwZXJzaXN0ZW5jZSBhZnRlciAzIHllYXJzICglKSIsIAogICAgICAgY29sb3VyID0gIk5vLiBQYXRjaGVzIikrCiAgc2NhbGVfY29sb3JfZGlzY3JldGUodHlwZSA9IHdlc19wYWxldHRlcyRaaXNzb3UxWzI6NV0sCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiMSIsICIzIiwgIjciLCAiMTQiKSkrCiAgdGhlbWVfYncoKQoKY29tYmluZWRfcGxvdAoKZ2dzYXZlKGZpbGVuYW1lID0gImNvbWJpbmVkX3Bsb3RfcGF0Y2hlcy5wZGYiLCBwbG90ID0gY29tYmluZWRfcGxvdCwgZGV2aWNlID0gInBkZiIsIHdpZHRoID0gNywgaGVpZ2h0ID0gNSwgcGF0aCA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL1Bsb3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMiKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoY29tYmluZWRfd2FuaW5nLCBhZXMoaW1tdW5pdHlfZHVyYXRpb24sIG1lYW5fcGVyY2VudF9pbmZlY3RlZCwgY29sb3VyID0gYXMuZmFjdG9yKHBhdGNoZXMpKSkrCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpICsKICBsYWJzKHggPSAiRHVyYXRpb24gb2YgaW1tdW5pdHkiLAogICAgICAgeSA9ICJQcm9wb3J0aW9uIGluZmVjdGVkIGF0IGVuZHBvaW50ICglKSIsIAogICAgICAgY29sb3VyID0gIlBhdGNoZXMiKSsKICBzY2FsZV9jb2xvcl9kaXNjcmV0ZSh0eXBlID0gd2VzX3BhbGV0dGVzJFppc3NvdTFbMjo1XSwKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCIxIiwgIjMiLCAiNyIsICIxNCIpKSsKICB0aGVtZV9idygpCmBgYAoKCiMjIFJlZmVyZW5jZXMKCgo=